#!/bin/sh

# Copyright (c) 2021-2025 刘富频
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


# last line mode :set foldmethod=marker
# command mode zM  fold close all
# command mode zR  fold open all

# {{{ coding convention

# 1. The variable/function name starts with underscore "_" means that it is a private variable/function.
# 2. 0 represents the boolean value false
# 3. 1 represents the boolean value true

# }}}
##############################################################################
# {{{ utils

COLOR_RED='\033[0;31m'          # Red
COLOR_GREEN='\033[0;32m'        # Green
COLOR_YELLOW='\033[0;33m'       # Yellow
COLOR_BLUE='\033[0;94m'         # Blue
COLOR_PURPLE='\033[0;35m'       # Purple
COLOR_OFF='\033[0m'             # Reset

print() {
    printf '%b' "$*"
}

echo() {
    printf '%b\n' "$*"
}

note() {
    printf '%b\n' "${COLOR_YELLOW}🔔  $*${COLOR_OFF}" >&2
}

warn() {
    printf '%b\n' "${COLOR_YELLOW}🔥  $*${COLOR_OFF}" >&2
}

success() {
    printf '%b\n' "${COLOR_GREEN}[✔] $*${COLOR_OFF}" >&2
}

error() {
    printf '%b\n' "${COLOR_RED}💔  xcpkg: $*${COLOR_OFF}" >&2
}

abort() {
    EXIT_STATUS_CODE="$1"
    shift
    printf '%b\n' "${COLOR_RED}💔  xcpkg: $*${COLOR_OFF}" >&2
    exit "$EXIT_STATUS_CODE"
}

step() {
    STEP_NUM=$(expr ${STEP_NUM-0} + 1)
    STEP_MESSAGE="$*"
    printf '\n%b\n' "${COLOR_PURPLE}=>> STEP ${STEP_NUM} : ${STEP_MESSAGE} ${COLOR_OFF}"
}

run() {
    echo "${COLOR_PURPLE}==>${COLOR_OFF} ${COLOR_GREEN}$@${COLOR_OFF}"
    eval "$@"
}

list_size() {
    printf '%s\n' "$#"
}

isInteger() {
    case "${1#[+-]}" in
        (*[!0123456789]*) return 1 ;;
        ('')              return 1 ;;
        (*)               return 0 ;;
    esac
}

isCrossBuild() {
    [ "$CROSS_COMPILING" = 1 ]
}

bppend_to_PATH() {
    case ":${PATH}:" in
        *:"$1":*) ;;
        *) export PATH="$1:$PATH" ;;
    esac
}

bppend_to_ACLOCAL_PATH() {
    case ":${ACLOCAL_PATH}:" in
        *:"$1":*) ;;
        *) export ACLOCAL_PATH="$1:$ACLOCAL_PATH" ;;
    esac
}

sedInPlace() {
    if [ "${DUMP_SED:-0}" = 1 ] ; then
        if [ -z "$SED" ] ; then
            SED="$(command -v gsed || command -v sed)" || abort 1 "command not found: gsed"
        fi

        export SED

        "$XCPKG_CORE_DIR/sed-in-place" "$@"
    else
        gsed -i "$@"
    fi
}

# git_checkout <URL> --ref-from=<FROM> --ref-to=<TO> --depth=<N> -B <CHECKOUT-BRANCH-NAME> -C <WORKDIR> --recursive
git_checkout() {
    OLDCWD="$PWD"

    unset GIT_FETCH_FROM_URL
    unset GIT_FETCH_FROM_REF
    unset GIT_FETCH_TO___REF
    unset GIT_FETCH_DEPTH
    unset GIT_FETCH_SUBMODULE_RECURSIVE
    unset GIT_CHECKOUT_BRANCH_NAME
    unset GIT_WORK_DIR

    if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
        GIT_FETCH_FROM_URL="$1"
    else
        GIT_FETCH_FROM_URL="$("$XCPKG_URL_TRANSFORM" "$1")"
    fi

    shift

    while [ -n "$1" ]
    do
        case $1 in
            --ref-from=*)
                GIT_FETCH_FROM_REF="${1#*=}"
                ;;
            --ref-to=*)
                GIT_FETCH_TO___REF="${1#*=}"
                ;;
            --depth=*)
                GIT_FETCH_DEPTH="${1#*=}"
                ;;
            -B) shift
                GIT_CHECKOUT_BRANCH_NAME="${1#*=}"
                ;;
            -C) shift
                GIT_WORK_DIR="$1"
                ;;
            --recursive)
                GIT_FETCH_SUBMODULE_RECURSIVE=1
                ;;
        esac
        shift
    done

    [ -z "$GIT_FETCH_DEPTH" ] && GIT_FETCH_DEPTH=1
    [ -z "$GIT_FETCH_FROM_REF" ] && GIT_FETCH_FROM_REF='HEAD'
    [ -z "$GIT_FETCH_TO___REF" ] && GIT_FETCH_TO___REF='refs/remotes/origin/master'

    [ -z "$GIT_CHECKOUT_BRANCH_NAME" ] && GIT_CHECKOUT_BRANCH_NAME="${GIT_FETCH_TO___REF##*/}"

    if [    -n "$GIT_WORK_DIR" ] ; then
        [   -d "$GIT_WORK_DIR" ] || run install -d "$GIT_WORK_DIR"
        run cd "$GIT_WORK_DIR"
    fi

    run git -c init.defaultBranch=master init
    run git remote add origin "$GIT_FETCH_FROM_URL"
    run git -c protocol.version=2 fetch --progress --depth="$GIT_FETCH_DEPTH" origin "$GIT_FETCH_FROM_REF:$GIT_FETCH_TO___REF"
    run git checkout --progress --force -B "$GIT_CHECKOUT_BRANCH_NAME" "$GIT_FETCH_TO___REF"

    git_submodule_update_recursive

    run cd "$OLDCWD"
}


git_submodule_update_recursive() {
    if [ -z "$1" ] ; then
        GIT_REPO_ROOT_DIR="$PWD"
    else
        GIT_REPO_ROOT_DIR="$1"
    fi

    GIT_SUBMODULE_HAVE="$(cd "$GIT_REPO_ROOT_DIR" && find . -type f -name '.gitmodules' -print -quit)"

    if [ -n "$GIT_SUBMODULE_HAVE" ] ; then
        if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
            run git submodule update --init --recursive
        else
            unset GIT_SUBMODULE_BASEDIR_STACK

            GIT_SUBMODULE_CONFIG_FILE_LIST="$(find "$GIT_REPO_ROOT_DIR" -type f -name '.gitmodules')"

            for f in $GIT_SUBMODULE_CONFIG_FILE_LIST
            do
                if [ -z "$GIT_SUBMODULE_BASEDIR_STACK" ] ; then
                    GIT_SUBMODULE_BASEDIR_STACK="${f%/*}"
                else
                    GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR_STACK;${f%/*}"
                fi
            done

            while [ -n "$GIT_SUBMODULE_BASEDIR_STACK" ]
            do
                case $GIT_SUBMODULE_BASEDIR_STACK in
                    *\;*) GIT_SUBMODULE_BASEDIR="${GIT_SUBMODULE_BASEDIR_STACK##*;}" ; GIT_SUBMODULE_BASEDIR_STACK="${GIT_SUBMODULE_BASEDIR_STACK%;*}" ;;
                    *)    GIT_SUBMODULE_BASEDIR="${GIT_SUBMODULE_BASEDIR_STACK}"     ; GIT_SUBMODULE_BASEDIR_STACK=
                esac

                run cd "$GIT_SUBMODULE_BASEDIR"

                GIT_SUBMODULE_NAME_LIST="$(sed -n '/\[submodule ".*"\]/p' .gitmodules | sed 's|\[submodule "\(.*\)"\]|\1|')"

                for GIT_SUBMODULE_NAME in $GIT_SUBMODULE_NAME_LIST
                do
                    GIT_SUBMODULE_PATH="$(git config --file=.gitmodules --get "submodule.$GIT_SUBMODULE_NAME.path")"
                    GIT_SUBMODULE_URL="$(git config --file=.gitmodules --get "submodule.$GIT_SUBMODULE_NAME.url")"
                    GIT_SUBMODULE_URI="$("$XCPKG_URL_TRANSFORM" "$GIT_SUBMODULE_URL")"

                    run git submodule set-url "$GIT_SUBMODULE_PATH" "$GIT_SUBMODULE_URI"
                done

                run git submodule update --init

                GIT_SUBMODULE_PATH_LIST="$(git submodule | sed 's|^ *||' | cut -d ' ' -f2)"

                for GIT_SUBMODULE_PATH in $GIT_SUBMODULE_PATH_LIST
                do
                    GIT_SUBMODULE_CONFIG_FILE_LIST="$(find "$GIT_SUBMODULE_PATH" -type f -name '.gitmodules')"

                    for f in $GIT_SUBMODULE_CONFIG_FILE_LIST
                    do
                        if [ -z "$GIT_SUBMODULE_BASEDIR_STACK" ] ; then
                            GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR/${f%/*}"
                        else
                            GIT_SUBMODULE_BASEDIR_STACK="$GIT_SUBMODULE_BASEDIR_STACK;$GIT_SUBMODULE_BASEDIR/${f%/*}"
                        fi
                    done
                done
            done
        fi
    fi
}

# check if the given two version match the condition
#
# condition:
# eq  equal
# ne  not equal
# gt  greater than
# lt  less than
# ge  greater than or equal
# le  less than or equal
#
# examples:
# version_match 1.15.3 eq 1.16.0
# version_match 1.15.3 lt 1.16.0
# version_match 1.15.3 gt 1.16.0
# version_match 1.15.3 le 1.16.0
# version_match 1.15.3 ge 1.16.0
version_match() {
    case $2 in
        eq)  [ "$1"  = "$3" ] ;;
        ne)  [ "$1" != "$3" ] ;;
        le)
            if [ "$1" = "$3" ] ; then
                return 0
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | head -n 1)" ]
            ;;
        ge)
            if [ "$1" = "$3" ] ; then
                return 0
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | tail -n 1)" ]
            ;;
        lt)
            if [ "$1" = "$3" ] ; then
                return 1
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | head -n 1)" ]
            ;;
        gt)
            if [ "$1" = "$3" ] ; then
                return 1
            fi
            [ "$1" = "$(printf '%s\n' "$1" "$3" | sort -V | tail -n 1)" ]
            ;;
        *)  abort 1 "version_match: unsupported operator: $2"
    esac
}

# }}}
##############################################################################
# {{{ wfetch

# wfetch <URL> [--uri=<URL-MIRROR>] [--sha256=<SHA256>] [-o <OUTPUT-PATH>] [-q] [--no-buffer]
#
# If -o <OUTPUT-PATH> option is unspecified, the result will be written to ./$(basename <URL>)
#
# If <OUTPUT-PATH> is -, then the result will be written to stdout.
#
# If <OUTPUT-PATH> is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath.
#
# If <OUTPUT-PATH> is treated as a directory, then it will be expanded to <OUTPUT-PATH>/$(basename <URL>)
#
# influential environment variable:
# XCPKG_URL_TRANSFORM
wfetch() {
    unset FETCH_UTS
    unset FETCH_SHA

    unset FETCH_URL
    unset FETCH_URI

    unset FETCH_PATH

    unset FETCH_OUTPUT_DIR
    unset FETCH_OUTPUT_FILEPATH
    unset FETCH_OUTPUT_FILENAME

    unset FETCH_BUFFER_FILEPATH

    unset FETCH_SHA256_EXPECTED

    unset FETCH_SILENT

    unset NOT_BUFFER

    [ -z "$1" ] && abort 1 "wfetch <URL> [OPTION]... , <URL> must be non-empty."

    if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
        FETCH_URL="$1"
    else
        FETCH_URL="$("$XCPKG_URL_TRANSFORM" "$1")" || return 1
    fi

    shift

    while [ -n "$1" ]
    do
        case $1 in
            --uri=*)
                FETCH_URI="${1#*=}"
                ;;
            --sha256=*)
                FETCH_SHA256_EXPECTED="${1#*=}"
                ;;
            -o) shift
                if [ -z "$1" ] ; then
                    abort 1 "wfetch <URL> -o <PATH> , <PATH> must be non-empty."
                else
                    FETCH_PATH="$1"
                fi
                ;;
            -q)
                FETCH_SILENT=1
                ;;
            --no-buffer)
                NOT_BUFFER=1
                ;;
            *)  abort 1 "wfetch <URL> [--uri=<URL-MIRROR>] [--sha256=<SHA256>] [-o <PATH>] [-q] , unrecognized option: $1"
        esac
        shift
    done

    case $FETCH_PATH in
        -)
            FETCH_BUFFER_FILEPATH='-'
            ;;
        .|'')
            FETCH_OUTPUT_DIR='.'
            FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}"
            ;;
        ..)
            FETCH_OUTPUT_DIR='..'
            FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}"
            ;;
        */)
            FETCH_OUTPUT_DIR="${FETCH_PATH%/}"
            FETCH_OUTPUT_FILEPATH="$FETCH_OUTPUT_DIR/${FETCH_URL##*/}"
            ;;
        *)
            FETCH_OUTPUT_DIR="$(dirname "$FETCH_PATH")"
            FETCH_OUTPUT_FILEPATH="$FETCH_PATH"
    esac

    if [ -n "$FETCH_OUTPUT_FILEPATH" ] ; then
        if [ -f "$FETCH_OUTPUT_FILEPATH" ] ; then
            if [ -n "$FETCH_SHA256_EXPECTED" ] ; then
                if [ "$(sha256sum "$FETCH_OUTPUT_FILEPATH" | cut -d ' ' -f1)" = "$FETCH_SHA256_EXPECTED" ] ; then
                    success "$FETCH_OUTPUT_FILEPATH already have been fetched."
                    return 0
                fi
            fi
        fi

        if [ "$NOT_BUFFER" = 1 ] ; then
            FETCH_BUFFER_FILEPATH="$FETCH_OUTPUT_FILEPATH"
        else
            FETCH_UTS="$(date +%s)"

            FETCH_SHA="$(printf '%s\n' "$FETCH_URL:$$:$FETCH_UTS" | sha256sum | cut -d ' ' -f1)"

            FETCH_BUFFER_FILEPATH="$FETCH_OUTPUT_DIR/$FETCH_SHA.tmp"
        fi
    fi

    for FETCH_TOOL in curl wget http aria2c axel
    do
        if command -v "$FETCH_TOOL" > /dev/null ; then
            break
        else
            unset FETCH_TOOL
        fi
    done

    if [ -z "$FETCH_TOOL" ] ; then
        abort 1 "none of curl wget http aria2c axel command was found, please install one of them then try again."
    fi

    if [                -n "$FETCH_OUTPUT_DIR" ] ; then
        if [ !          -d "$FETCH_OUTPUT_DIR" ] ; then
            run install -d "$FETCH_OUTPUT_DIR" || return 1
        fi
    fi

    case $FETCH_TOOL in
        curl)
            FETCH_ARGS='--fail --retry 20 --retry-delay 30 --location'

            if [ "$FETCH_SILENT" = 1 ] ; then
                FETCH_ARGS="$FETCH_ARGS --no-progress-meter"
            fi

            if [ -n "$XCPKG_DNS_SERVERS" ] ; then
                FETCH_ARGS="$FETCH_ARGS --dns-servers $XCPKG_DNS_SERVERS"
            fi

            if [ -n "$SSL_CERT_FILE" ] ; then
                FETCH_ARGS="$FETCH_ARGS --cacert $SSL_CERT_FILE"
            fi

            FETCH_ARGS="$FETCH_ARGS -o '$FETCH_BUFFER_FILEPATH'"
            ;;
        wget)
            FETCH_ARGS="--timeout=60 -O '$FETCH_BUFFER_FILEPATH'"
            ;;
        http)
            FETCH_ARGS="--timeout=60 -o '$FETCH_BUFFER_FILEPATH'"
            ;;
        aria2c)
            FETCH_ARGS="-d '$FETCH_OUTPUT_DIR' -o '$FETCH_OUTPUT_FILENAME'"
            ;;
        axel)
            FETCH_ARGS="-o '$FETCH_BUFFER_FILEPATH'"
            ;;
        *)  abort 1 "wfetch() unimplementation: $FETCH_TOOL"
            ;;
    esac

    for i in 1 2 3 4
    do
        case $i in
            1)  URL="$FETCH_URL"
                ;;
            2)  if [ -z "$FETCH_URI" ] ; then
                    if [ -z "$PACKAGE_NAME" ] ; then
                        continue
                    fi

                    URI="${FETCH_URL%%'?'*}"
                    URL="https://distfiles.macports.org/${PACKAGE_NAME%@*}/${URI##*/}"
                else
                    if [ -n "$XCPKG_URL_TRANSFORM" ] ; then
                        URL="$("$XCPKG_URL_TRANSFORM" "$FETCH_URI")" || return 1
                    else
                        URL="$FETCH_URI"
                    fi
                fi
                ;;
            3)  case $FETCH_URL in
                    https://ftp.gnu.org/gnu/*)
                        URL="$(printf '%s\n' "$FETCH_URL" | sed 's|ftp\.gnu\.org|ftpmirror.gnu.org|')"
                        ;;
                    *)  continue
                esac
                ;;
            4)  URI="${FETCH_URL%%'?'*}"
                URL="https://fossies.org/linux/misc/${URI##*/}"
                ;;
        esac

        run "$FETCH_TOOL $FETCH_ARGS '$URL'" && break
    done

    [ $? -eq 0 ] || return 1

    if [ -n "$FETCH_OUTPUT_FILEPATH" ] ; then
        if [ -n "$FETCH_SHA256_EXPECTED" ] ; then
            FETCH_SHA256_ACTUAL="$(sha256sum "$FETCH_BUFFER_FILEPATH" | cut -d ' ' -f1)"

            if [ "$FETCH_SHA256_ACTUAL" != "$FETCH_SHA256_EXPECTED" ] ; then
                abort 1 "sha256sum mismatch.\n    expect : $FETCH_SHA256_EXPECTED\n    actual : $FETCH_SHA256_ACTUAL\n"
            fi
        fi

        if [ "$NOT_BUFFER" != 1 ] ; then
            run mv "$FETCH_BUFFER_FILEPATH" "$FETCH_OUTPUT_FILEPATH"
        fi
    fi
}

# __load_formula_repository_config <REPO-NAME> [REPO-PATH]
  __load_formula_repository_config() {
    FORMULA_REPO_NAME="$1"
    FORMULA_REPO_PATH="$XCPKG_FORMULA_REPO_ROOT/$1"
    FORMULA_REPO_CONFIG_FILEPATH="$FORMULA_REPO_PATH/.xcpkg-formula-repo.yml"

    [ -d "$FORMULA_REPO_PATH" ] || abort 1 "formula repository '$1' does not exist."
    [ -f "$FORMULA_REPO_CONFIG_FILEPATH" ] || abort 1 "formula repository '$1' is broken."

    FORMULA_REPO_URL=
    FORMULA_REPO_BRANCH=
    FORMULA_REPO_PINNED=
    FORMULA_REPO_ENABLED=
    FORMULA_REPO_TIMESTAMP_CREATED=
    FORMULA_REPO_TIMESTAMP_UPDATED=

    FORMULA_REPO_URL="$(yq .url "$FORMULA_REPO_CONFIG_FILEPATH")"

    [ "$FORMULA_REPO_URL" = null ] && abort 1 "formula repository '$1' is broken."

    FORMULA_REPO_BRANCH="$(yq .branch "$FORMULA_REPO_CONFIG_FILEPATH")"

    [ "$FORMULA_REPO_BRANCH" = null ] && abort 1 "formula repository '$1' is broken."

    FORMULA_REPO_PINNED="$(yq .pinned "$FORMULA_REPO_CONFIG_FILEPATH")"

    case $FORMULA_REPO_PINNED in
        0|1) ;;
        *)   abort 1 "formula repository '$1' is broken."
    esac

    FORMULA_REPO_ENABLED="$(yq .enabled "$FORMULA_REPO_CONFIG_FILEPATH")"

    case $FORMULA_REPO_ENABLED in
        0|1) ;;
        *)   abort 1 "formula repository '$1' is broken."
    esac

    FORMULA_REPO_TIMESTAMP_CREATED="$(yq .created "$FORMULA_REPO_CONFIG_FILEPATH")"

    [ "${#FORMULA_REPO_TIMESTAMP_CREATED}" -eq 10 ] || abort 1 "formula repository '$1' is broken."

    FORMULA_REPO_TIMESTAMP_UPDATED="$(yq .updated "$FORMULA_REPO_CONFIG_FILEPATH")"

    if [ "$FORMULA_REPO_TIMESTAMP_UPDATED" = null ] ; then
           FORMULA_REPO_TIMESTAMP_UPDATED=
    else
        [ "${#FORMULA_REPO_TIMESTAMP_UPDATED}" -eq 10 ] || abort 1 "formula repository '$1' is broken."
    fi
}

# }}}
##############################################################################
# {{{ xcpkg formula-repo-add

# __create_a_formula_repository_then_sync_it <REPO-NAME> <REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]
  __create_a_formula_repository_then_sync_it() {
    [ -z "$1" ] && abort 1 "please specify a repository name."
    [ -z "$2" ] && abort 1 "please specify a repository url."

    FORMULA_REPO_NAME="$1"
    FORMULA_REPO_URL="$2"

    if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
        GIT_FETCH_URL="$FORMULA_REPO_URL"
    else
        GIT_FETCH_URL="$("$XCPKG_URL_TRANSFORM" "$FORMULA_REPO_URL")"
    fi

    shift 2

    FORMULA_REPO_BRANCH=
    FORMULA_REPO_PINNED=
    FORMULA_REPO_ENABLED=

    while [ -n "$1" ]
    do
        case $1 in
            --branch=*)
                FORMULA_REPO_BRANCH="${1#*=}"
                ;;
            --pin)
                FORMULA_REPO_PINNED=1
                ;;
            --unpin)
                FORMULA_REPO_PINNED=0
                ;;
            --enable)
                FORMULA_REPO_ENABLED=1
                ;;
            --disable)
                FORMULA_REPO_ENABLED=0
                ;;
            *)  abort 1 "unrecognized argument: $1"
        esac
        shift
    done

    FORMULA_REPO_BRANCH="${FORMULA_REPO_BRANCH:-master}"
    FORMULA_REPO_PINNED="${FORMULA_REPO_PINNED:-0}"
    FORMULA_REPO_ENABLED="${FORMULA_REPO_ENABLED:-1}"

    FORMULA_REPO_PATH="$XCPKG_FORMULA_REPO_ROOT/$FORMULA_REPO_NAME"

    if [ -d "$FORMULA_REPO_PATH" ] ; then
        abort 1 "formula repository '$FORMULA_REPO_NAME' already exists."
    fi

    printf '%b\n' "${COLOR_PURPLE}==> xcpkg formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF} ${COLOR_PURPLE}is being added"

    SESSION_DIR="$XCPKG_HOME/run/$$/$FORMULA_REPO_NAME"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    run git -c init.defaultBranch=master init
    run git remote add origin "$GIT_FETCH_URL"
    run git -c protocol.version=2 fetch --progress origin "+refs/heads/$FORMULA_REPO_BRANCH:refs/remotes/origin/$FORMULA_REPO_BRANCH"
    run git checkout --progress --force -B "$FORMULA_REPO_BRANCH" "refs/remotes/origin/$FORMULA_REPO_BRANCH"

    cat > .xcpkg-formula-repo.yml <<EOF
url: $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $TIMESTAMP_UNIX
EOF

    run install -d        "$XCPKG_FORMULA_REPO_ROOT"
    run mv "$SESSION_DIR" "$XCPKG_FORMULA_REPO_ROOT/"
}

# }}}
##############################################################################
# {{{ xcpkg formula-repo-init

# __create_a_formula_repository <REPO-NAME> <REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]
  __create_a_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."
    [ -z "$2" ] && abort 1 "please specify a repository url."

    FORMULA_REPO_NAME="$1"

    if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
        FORMULA_REPO_URL="$2"
    else
        FORMULA_REPO_URL="$("$XCPKG_URL_TRANSFORM" "$2")"
    fi

    shift 2

    FORMULA_REPO_BRANCH=
    FORMULA_REPO_PINNED=
    FORMULA_REPO_ENABLED=

    while [ -n "$1" ]
    do
        case $1 in
            --branch=*)
                FORMULA_REPO_BRANCH="${1#*=}"
                ;;
            --pin)
                FORMULA_REPO_PINNED=1
                ;;
            --unpin)
                FORMULA_REPO_PINNED=0
                ;;
            --enable)
                FORMULA_REPO_ENABLED=1
                ;;
            --disable)
                FORMULA_REPO_ENABLED=0
                ;;
            *)  abort 1 "unrecognized argument: $1"
        esac
        shift
    done

    FORMULA_REPO_BRANCH="${FORMULA_REPO_BRANCH:-master}"
    FORMULA_REPO_PINNED="${FORMULA_REPO_PINNED:-1}"
    FORMULA_REPO_ENABLED="${FORMULA_REPO_ENABLED:-1}"

    FORMULA_REPO_PATH="$XCPKG_FORMULA_REPO_ROOT/$FORMULA_REPO_NAME"

    if [ -d "$FORMULA_REPO_PATH" ] ; then
        abort 1 "formula repository '$FORMULA_REPO_NAME' already exists."
    fi

    printf '%b\n' "${COLOR_PURPLE}==> xcpkg formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF} ${COLOR_PURPLE}is being created"

    SESSION_DIR="$XCPKG_HOME/run/$$/$FORMULA_REPO_NAME"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    run git -c init.defaultBranch=master init
    run git remote add origin "$FORMULA_REPO_URL"

    cat > .xcpkg-formula-repo.yml <<EOF
url: $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $TIMESTAMP_UNIX
EOF

    run install -d        "$XCPKG_FORMULA_REPO_ROOT"
    run mv "$SESSION_DIR" "$XCPKG_FORMULA_REPO_ROOT/"
}

# }}}
##############################################################################
# {{{ xcpkg formula-repo-del

# __delete_a_formula_repository <REPO-NAME>
  __delete_a_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."

    [ "$1" = 'official-core' ] && abort 1 "formula repository 'official-core' is not allowed to delete."

    if [ -d    "$XCPKG_FORMULA_REPO_ROOT/$1" ] ; then
        rm -rf "$XCPKG_FORMULA_REPO_ROOT/$1"
    else
        abort 1 "formula repository '$1' does not exist."
    fi
}

# }}}
##############################################################################
# {{{ xcpkg formula-repo-sync

# __sync_the_given_formula_repository <REPO-NAME>
  __sync_the_given_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."

    __load_formula_repository_config "$1"

    [ "$FORMULA_REPO_PINNED" = 1 ] && abort 1 "formula repository '$FORMULA_REPO_NAME' is pinned."

    if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
        GIT_FETCH_URL="$FORMULA_REPO_URL"
    else
        GIT_FETCH_URL="$("$XCPKG_URL_TRANSFORM" "$FORMULA_REPO_URL")"
    fi

    printf '%b\n' "${COLOR_PURPLE}==> xcpkg formula repository${COLOR_OFF} ${COLOR_GREEN}$FORMULA_REPO_NAME${COLOR_OFF} ${COLOR_PURPLE}is being updated"

    run cd "$FORMULA_REPO_PATH"
    run git remote set-url origin "$GIT_FETCH_URL"
    run git -c protocol.version=2 fetch --progress origin "+refs/heads/$FORMULA_REPO_BRANCH:refs/remotes/origin/$FORMULA_REPO_BRANCH"
    run git checkout --progress --force -B "$FORMULA_REPO_BRANCH" "refs/remotes/origin/$FORMULA_REPO_BRANCH"

    cat > .xcpkg-formula-repo.yml <<EOF
url: $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $FORMULA_REPO_TIMESTAMP_CREATED
updated: $TIMESTAMP_UNIX
EOF
}

# }}}
##############################################################################
# {{{ xcpkg formula-repo-conf

# __conf_the_given_formula_repository <REPO-NAME> [--url=VALUE --branch=VALUE --pin/--unpin --enable/--disable]
  __conf_the_given_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."
    [ -z "$2" ] && abort 1 "at least one option should be given. supported options are: --url=VALUE --branch=VALUE --pin/--unpin --enable/--disable"

    __load_formula_repository_config "$1"

    shift

    while [ -n "$1" ]
    do
        case $1 in
            --url=*)
                FORMULA_REPO_URL="${1#*=}"

                if [ -z "$FORMULA_REPO_URL" ] ; then
                    abort 1 "--url=<VALUE> , <VALUE> should be non-empty."
                else
                    FORMULA_REPO_URL="$FORMULA_REPO_URL"
                fi
                ;;
            --branch=*)
                FORMULA_REPO_BRANCH="${1#*=}"

                if [ -z "$FORMULA_REPO_BRANCH" ] ; then
                    abort 1 "--branch=<VALUE> , <VALUE> should be non-empty."
                else
                    FORMULA_REPO_BRANCH="$FORMULA_REPO_BRANCH"
                fi
                ;;
            --pin)
                FORMULA_REPO_PINNED=1
                ;;
            --unpin)
                FORMULA_REPO_PINNED=0
                ;;
            --enable)
                FORMULA_REPO_ENABLED=1
                ;;
            --disable)
                FORMULA_REPO_ENABLED=0
                ;;
            *)  abort 1 "unrecognized argument: $1"
        esac
        shift
    done

    if [ -z "$FORMULA_REPO_TIMESTAMP_UPDATED" ] ; then
        cat > "$FORMULA_REPO_PATH/.xcpkg-formula-repo.yml" <<EOF
url:  $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $FORMULA_REPO_TIMESTAMP_CREATED
EOF
    else
        cat > "$FORMULA_REPO_PATH/.xcpkg-formula-repo.yml" <<EOF
url:  $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $FORMULA_REPO_TIMESTAMP_CREATED
updated: $FORMULA_REPO_TIMESTAMP_UPDATED
EOF
fi
}

# }}}
##############################################################################
# {{{ xcpkg formula-repo-info

# __info_the_given_formula_repository <REPO-NAME>
  __info_the_given_formula_repository() {
    [ -z "$1" ] && abort 1 "please specify a repository name."

    __load_formula_repository_config "$1"

    case $FORMULA_REPO_PINNED in
        0)  FORMULA_REPO_PINNED=no  ;;
        1)  FORMULA_REPO_PINNED=yes ;;
    esac

    case $FORMULA_REPO_ENABLED in
        0)  FORMULA_REPO_ENABLED=no  ;;
        1)  FORMULA_REPO_ENABLED=yes ;;
    esac

    cat <<EOF
name: $FORMULA_REPO_NAME
path: $FORMULA_REPO_PATH
url:  $FORMULA_REPO_URL
branch: $FORMULA_REPO_BRANCH
pinned: $FORMULA_REPO_PINNED
enabled: $FORMULA_REPO_ENABLED
created: $(date -d "@$FORMULA_REPO_TIMESTAMP_CREATED" '+%Y-%m-%d %H:%M:%S%:z')
EOF

    if [ -n "$FORMULA_REPO_TIMESTAMP_UPDATED" ] ; then
        printf 'updated: %s\n' "$(date -d "@$FORMULA_REPO_TIMESTAMP_UPDATED" '+%Y-%m-%d %H:%M:%S%:z')"
    fi
}

# }}}
##############################################################################
# {{{ xcpkg formula-repo-list

__list_available_formula_repositories() {
    [ -d "$XCPKG_FORMULA_REPO_ROOT" ] || return 0

    for item in $(cd "$XCPKG_FORMULA_REPO_ROOT" && ls)
    do
        if [ -f "$XCPKG_FORMULA_REPO_ROOT/$item/.xcpkg-formula-repo.yml" ] ; then
            __info_the_given_formula_repository "$item"
        fi
    done
}

# }}}
##############################################################################
# {{{ xcpkg update

__sync_available_formula_repositories() {
    [ -d "$XCPKG_FORMULA_REPO_ROOT" ] && {
        for item in $(cd "$XCPKG_FORMULA_REPO_ROOT" && ls)
        do
            if [ -f "$XCPKG_FORMULA_REPO_ROOT/$item/.xcpkg-formula-repo.yml" ] ; then
                __sync_the_given_formula_repository "$item"
            fi
        done
    }

    [ -d "$XCPKG_FORMULA_REPO_ROOT/official-core" ] || {
        __create_a_formula_repository_then_sync_it official-core "$XCPKG_OFFICIAL_FORMULA_REPO_URL"
    }
}

# __path_of_formula_of_the_given_package <PACKAGE-NAME>
  __path_of_formula_of_the_given_package() {
    [ -z "$1" ] && abort 1 "__path_of_formula_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified."

    if [ -n "$XCPKG_FORMULA_SEARCH_DIRS" ] ; then
        export IFS=':'

        for FORMULA_SEARCH_DIR in $XCPKG_FORMULA_SEARCH_DIRS
        do
            FORMULA_FILEPATH="$FORMULA_SEARCH_DIR/$1.yml"

            if [ -f           "$FORMULA_FILEPATH" ] ; then
                printf '%s\n' "$FORMULA_FILEPATH"
                return 0
            fi
        done

        unset IFS
    fi

    [ -d "$XCPKG_FORMULA_REPO_ROOT" ] || return 0

    FORMULA_REPOSITORY_NAMES=

    for item in $(cd "$XCPKG_FORMULA_REPO_ROOT" && ls)
    do
        if [ -f "$XCPKG_FORMULA_REPO_ROOT/$item/.xcpkg-formula-repo.yml" ] ; then
            FORMULA_REPOSITORY_NAMES="$FORMULA_REPOSITORY_NAMES $item"
        fi
    done

    for FORMULA_REPOSITORY_NAME in $FORMULA_REPOSITORY_NAMES
    do
        FORMULA_FILEPATH="$XCPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula/$1.yml"

        if [ -f           "$FORMULA_FILEPATH" ] ; then
            printf '%s\n' "$FORMULA_FILEPATH"
            return 0
        fi
    done
}


# }}}
##############################################################################
# {{{ operations of formula

filetype_from_url() {
    # remove query params
    URL="${1%%'?'*}"

    FNAME="${URL##*/}"

    case $FNAME in
        *.tar.gz|*.tgz)
            printf '%s\n' '.tgz'
            ;;
        *.tar.lz|*.tlz)
            printf '%s\n' '.tlz'
            ;;
        *.tar.xz|*.txz)
            printf '%s\n' '.txz'
            ;;
        *.tar.bz2|*.tbz2)
            printf '%s\n' '.tbz2'
            ;;
        *.*)printf '%s\n' ".${FNAME##*.}"
    esac
}

# __load_formula_of_the_given_package <PACKAGE-NAME> [FORMULA-FILEPATH]
  __load_formula_of_the_given_package() {
    if [ -z "$1" ] ; then
        abort 1 "__load_formula_of_the_given_package <PACKAGE-NAME> [FORMULA-FILEPATH], <PACKAGE-NAME> is unspecified."
    else
        PACKAGE_NAME="$1"
        PACKAGE_NAME_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')
    fi

    #########################################################################################

    if [ -z "$2" ] ; then
        PACKAGE_FORMULA_FILEPATH="$(__path_of_formula_of_the_given_package "$1")"

        if [ -z "$PACKAGE_FORMULA_FILEPATH" ] ; then
            abort 1 "package '$1' is not available."
        fi
    else
        PACKAGE_FORMULA_FILEPATH="$2"
    fi

    #########################################################################################

    unset PACKAGE_PKGTYPE

    unset PACKAGE_SUMMARY

    unset PACKAGE_LICENSE

    unset PACKAGE_VERSION
    unset PACKAGE_VERSION_MAJOR
    unset PACKAGE_VERSION_MINOR
    unset PACKAGE_VERSION_PATCH
    unset PACKAGE_VERSION_TWEAK

    unset PACKAGE_WEB_URL

    unset PACKAGE_GIT_URL
    unset PACKAGE_GIT_SHA
    unset PACKAGE_GIT_REF
    unset PACKAGE_GIT_NTH

    unset PACKAGE_SRC_URL
    unset PACKAGE_SRC_URI
    unset PACKAGE_SRC_SHA
    unset PACKAGE_SRC_FILENAME
    unset PACKAGE_SRC_FILETYPE
    unset PACKAGE_SRC_FILEPATH

    unset PACKAGE_FIX_URL
    unset PACKAGE_FIX_URI
    unset PACKAGE_FIX_SHA
    unset PACKAGE_FIX_OPT
    unset PACKAGE_FIX_FILENAME
    unset PACKAGE_FIX_FILETYPE
    unset PACKAGE_FIX_FILEPATH

    unset PACKAGE_RES_URL
    unset PACKAGE_RES_URI
    unset PACKAGE_RES_SHA
    unset PACKAGE_RES_FILENAME
    unset PACKAGE_RES_FILETYPE
    unset PACKAGE_RES_FILEPATH

    # space-separated    perl modules that are depended by this package when installing, which will be installed via cpan
    unset PACKAGE_DEP_PLM

    # space-separated python packages that are depended by this package when installing, which will be installed via pip3
    unset PACKAGE_DEP_PYM

    # space-separated   uppm packages that are depended by this package when installing, which will be installed via uppm
    unset PACKAGE_DEP_UPP

    # space-separated xcpkg packages that are depended by this package when installing and/or runtime, which will be installed via xcpkg
    unset PACKAGE_DEP_PKG

    # space-separated xcpkg pkg-config packages that are depended by this package while linking
    unset PACKAGE_DEP_LIB

    unset PACKAGE_PPFLAGS
    unset PACKAGE_CCFLAGS
    unset PACKAGE_XXFLAGS
    unset PACKAGE_OCFLAGS
    unset PACKAGE_OXFLAGS
    unset PACKAGE_LDFLAGS

    unset PACKAGE_DOFETCH
    unset PACKAGE_DO12345
    unset PACKAGE_DOPATCH
    unset PACKAGE_PREPARE
    unset PACKAGE_DOBUILD
    unset PACKAGE_DOTWEAK

    unset PACKAGE_PATCHES
    unset PACKAGE_RESLIST

    unset PACKAGE_BINDENV
    unset PACKAGE_WRAPPER
    unset PACKAGE_CAVEATS

    unset PACKAGE_BSYSTEM
    unset PACKAGE_BSYSTEM_MASTER

    unset PACKAGE_USE_BSYSTEM_GO
    unset PACKAGE_USE_BSYSTEM_GN
    unset PACKAGE_USE_BSYSTEM_WAF
    unset PACKAGE_USE_BSYSTEM_ZIG
    unset PACKAGE_USE_BSYSTEM_RAKE
    unset PACKAGE_USE_BSYSTEM_NINJA
    unset PACKAGE_USE_BSYSTEM_GMAKE
    unset PACKAGE_USE_BSYSTEM_CMAKE
    unset PACKAGE_USE_BSYSTEM_XMAKE
    unset PACKAGE_USE_BSYSTEM_MESON
    unset PACKAGE_USE_BSYSTEM_CARGO
    unset PACKAGE_USE_BSYSTEM_CABAL
    unset PACKAGE_USE_BSYSTEM_AUTOGENSH
    unset PACKAGE_USE_BSYSTEM_AUTOTOOLS
    unset PACKAGE_USE_BSYSTEM_CONFIGURE
    unset PACKAGE_USE_BSYSTEM_NETSURF

    # directory relative to $PACKAGE_WORKING_DIR/src, which contains build script such as autogen.sh, configure, Makefile, CMakeLists.txt, meson.build, Cargo.toml, xmake.lua, etc.
    unset PACKAGE_BSCRIPT

    # whether to build in build script directory, otherwise build in build dir
    unset PACKAGE_BINBSTD

    unset PACKAGE_LTOABLE

    # whether the installed files can be moved/copied to other locations
    unset PACKAGE_MOVABLE

    unset PACKAGE_SUPPORT_BUILD_IN_PARALLEL
    unset PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE

    unset PACKAGE_DEVELOPER

    #########################################################################################

    PACKAGE_PKGTYPE="$(yq '.pkgtype | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_SUMMARY="$(yq '.summary | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_LICENSE="$(yq '.license | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_VERSION="$(yq '.version | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_WEB_URL="$(yq '.web-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_GIT_URL="$(yq '.git-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_GIT_SHA="$(yq '.git-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_GIT_REF="$(yq '.git-ref | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_GIT_NTH="$(yq '.git-nth | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_SRC_URL="$(yq '.src-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_SRC_URI="$(yq '.src-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_SRC_SHA="$(yq '.src-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_FIX_URL="$(yq '.fix-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_FIX_URI="$(yq '.fix-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_FIX_SHA="$(yq '.fix-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_FIX_OPT="$(yq '.fix-opt | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_RES_URL="$(yq '.res-url | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_RES_URI="$(yq '.res-uri | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_RES_SHA="$(yq '.res-sha | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_DEP_PKG="$(yq '.dep-pkg | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_LIB="$(yq '.dep-lib | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_UPP="$(yq '.dep-upp | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_PYM="$(yq '.dep-pip | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DEP_PLM="$(yq '.dep-plm | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_BSYSTEM="$(yq '.bsystem | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_BSCRIPT="$(yq '.bscript | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_BINBSTD="$(yq '.binbstd | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_LTOABLE="$(yq '.ltoable | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_MOVABLE="$(yq '.movable | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_PPFLAGS="$(yq '.ppflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_CCFLAGS="$(yq '.ccflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_XXFLAGS="$(yq '.xxflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_OCFLAGS="$(yq '.ocflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_OXFLAGS="$(yq '.oxflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_LDFLAGS="$(yq '.ldflags | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_DOFETCH="$(yq '.dofetch | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DO12345="$(yq '.do12345 | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DOPATCH="$(yq '.dopatch | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_PREPARE="$(yq '.prepare | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DOBUILD="$(yq '.install | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_DOTWEAK="$(yq '.dotweak | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_BINDENV="$(yq '.bindenv | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_WRAPPER="$(yq '.wrapper | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_CAVEATS="$(yq '.caveats | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_PATCHES="$(yq '.patches | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"
    PACKAGE_RESLIST="$(yq '.reslist | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_DEVELOPER="$(yq '.developer | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_SUPPORT_BUILD_IN_PARALLEL="$(yq '.parallel | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE="$(yq '.mslable | select(. != null)' "$PACKAGE_FORMULA_FILEPATH")"

    #########################################################################################

    if [ -z "$PACKAGE_SUMMARY" ] ; then
        abort 1 "summary mapping not found in $PACKAGE_FORMULA_FILEPATH"
    fi

    if [ -n "$PACKAGE_FIX_URL" ] && [ -n "$PACKAGE_PATCHES" ] ; then
        abort 1 "fix-url and patches mapping shouldn't be used together in $PACKAGE_FORMULA_FILEPATH"
    fi

    if [ -n "$PACKAGE_RES_URL" ] && [ -n "$PACKAGE_RESLIST" ] ; then
        abort 1 "res-url and reslist mapping shouldn't be used together in $PACKAGE_FORMULA_FILEPATH"
    fi

    if [ -n "$PACKAGE_GIT_NTH" ] ; then
        isInteger "$PACKAGE_GIT_NTH" || abort "the value of git-nth mapping should be an integer."
    fi

    #########################################################################################

    unset PACKAGE_NEED_CURL
    unset PACKAGE_NEED_BTAR

    #########################################################################################

    if [ -n "$PACKAGE_SRC_URL" ] ; then
        case $PACKAGE_SRC_URL in
            dir://*)
                PACKAGE_SRC_FILETYPE=.dir
                PACKAGE_SRC_FILEPATH=$(printf '%s\n' "$PACKAGE_SRC_URL" | cut -c7-)

                if [ -z "$PACKAGE_VERSION" ] ; then
                    PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')"
                fi
                ;;
            file://*)
                PACKAGE_SRC_FILEPATH=$(printf '%s\n' "$PACKAGE_SRC_URL" | cut -c8-)
                PACKAGE_SRC_FILENAME="$(basename "$PACKAGE_SRC_FILEPATH")"
                PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_FILENAME")"

                if [ -z "$PACKAGE_VERSION" ] ; then
                    PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')"
                fi
                ;;
            *)  PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_URL")"
                PACKAGE_SRC_FILENAME="$PACKAGE_SRC_SHA$PACKAGE_SRC_FILETYPE"
                PACKAGE_SRC_FILEPATH="$XCPKG_DOWNLOADS_DIR/$PACKAGE_SRC_FILENAME"

                if [ -z "$PACKAGE_SRC_SHA" ] ; then
                    abort 1 "src-sha mapping not found in $PACKAGE_FORMULA_FILEPATH"
                fi

                if [ -z "$PACKAGE_GIT_URL" ] ; then
                    case $PACKAGE_SRC_URL in
                        https://github.com/*/*/releases/*)
                            PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/releases/*}"
                            ;;
                        https://github.com/*/*/archive/*)
                            PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/archive/*}"
                            ;;
                        https://gitlab.com/*/*/-/archive/*)
                            PACKAGE_GIT_URL="${PACKAGE_SRC_URL%%/-/archive/*}"
                            ;;
                    esac
                fi

                if [ -z "$PACKAGE_VERSION" ] ; then
                    PACKAGE_VERSION="$(basename "$PACKAGE_SRC_URL" | tr '_@' - | sed -e 's|\.tar\.[glx]z$||' -e 's|\.tar\.bz2$||' -e 's|\.t[glx]z$||' -e 's|\.zip$||' -e 's|-stable||' -e 's|-source||' -e 's|[-.]src$||' -e 's|\.orig||' -e 's|\.crate||' | awk -F- '{print $NF}')"
                    case $PACKAGE_VERSION in
                        '') abort 1 "version mapping not found in $PACKAGE_FORMULA_FILEPATH" ;;
                        v*) PACKAGE_VERSION="${PACKAGE_VERSION#v}"
                    esac
                fi

                PACKAGE_NEED_CURL=1

                case $PACKAGE_SRC_FILETYPE in
                    .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                        PACKAGE_NEED_BTAR=1
                esac
        esac
    else
        if [ -n "$PACKAGE_GIT_URL" ] ; then
            PACKAGE_SRC_FILETYPE=.git
            PACKAGE_SRC_FILEPATH=.git

            if [ -z "$PACKAGE_VERSION" ] && [ -z "$PACKAGE_GIT_SHA" ] && [ -n "$PACKAGE_GIT_REF" ] ; then
                PACKAGE_GIT_REF_NAME="${PACKAGE_GIT_REF##*/}"

                case $PACKAGE_GIT_REF_NAME in
                    v*) PACKAGE_VERSION="${PACKAGE_GIT_REF_NAME#v}" ;;
                    [0-9]*) PACKAGE_VERSION="$PACKAGE_GIT_REF_NAME"
                esac
            fi

            if [ -z "$PACKAGE_VERSION" ] ; then
                PACKAGE_VERSION="$(date -u -d "@$TIMESTAMP_UNIX" '+%Y.%m.%d')"
            fi

            PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP git"
        fi
    fi

    #########################################################################################

    if [ -z "$PACKAGE_WEB_URL" ] && [ -z "$PACKAGE_GIT_URL" ] ; then
        abort 1 "neither web-url nor git-url mapping was found in $PACKAGE_FORMULA_FILEPATH"
    fi

    #########################################################################################

    [ -n "$PACKAGE_FIX_URL" ] && {
        [ -z "$PACKAGE_FIX_SHA" ] && abort 1 "fix-sha mapping not found in $PACKAGE_FORMULA_FILEPATH"

        PACKAGE_FIX_FILETYPE="$(filetype_from_url "$PACKAGE_FIX_URL")"
        PACKAGE_FIX_FILENAME="$PACKAGE_FIX_SHA$PACKAGE_FIX_FILETYPE"
        PACKAGE_FIX_FILEPATH="$XCPKG_DOWNLOADS_DIR/$PACKAGE_FIX_FILENAME"

        PACKAGE_NEED_CURL=1

        case $PACKAGE_FIX_FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                PACKAGE_NEED_BTAR=1
        esac
    }

    #########################################################################################

    [ -n "$PACKAGE_RES_URL" ] && {
        [ -z "$PACKAGE_RES_SHA" ] && abort 1 "res-sha mapping not found in $PACKAGE_FORMULA_FILEPATH"

        PACKAGE_RES_FILETYPE="$(filetype_from_url "$PACKAGE_RES_URL")"
        PACKAGE_RES_FILENAME="$PACKAGE_RES_SHA$PACKAGE_RES_FILETYPE"
        PACKAGE_RES_FILEPATH="$XCPKG_DOWNLOADS_DIR/$PACKAGE_RES_FILENAME"

        PACKAGE_NEED_CURL=1

        case $PACKAGE_RES_FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                PACKAGE_NEED_BTAR=1
        esac
    }

    #########################################################################################

    for LINE in $PACKAGE_PATCHES $PACKAGE_RESLIST
    do
        SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
        URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"

        FILETYPE="$(filetype_from_url "$URL")"

        if [ "${#SHA}" -ne 64 ] ; then
            abort 1 "not a sha256sum in line: $LINE in file: $PACKAGE_FORMULA_FILEPATH"
        fi

        PACKAGE_NEED_CURL=1

        case $FILETYPE in
            .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                PACKAGE_NEED_BTAR=1
        esac
    done

    #########################################################################################

    [ "$PACKAGE_NEED_CURL" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP curl"
    [ "$PACKAGE_NEED_BTAR" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP bsdtar"

    #########################################################################################

    [ -n "$PACKAGE_VERSION" ] && {
        PACKAGE_VERSION_MAJOR="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f1)"
        PACKAGE_VERSION_MINOR="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f2)"
        PACKAGE_VERSION_PATCH="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f3)"
        PACKAGE_VERSION_TWEAK="$(printf '%s\n' "$PACKAGE_VERSION" | cut -d. -f4)"
    }

    #########################################################################################

    if [     -z "$PACKAGE_BSYSTEM" ] ; then
        if [ -z "$PACKAGE_DOBUILD" ] ; then
            abort 1 "neither bsystem nor install mapping was found in $PACKAGE_FORMULA_FILEPATH"
        else
            for FirstWordOfLineInInstallActions in $(printf '%s\n' "$PACKAGE_DOBUILD" | sed 's|^[[:space:]]*||' | cut -d ' ' -f1)
            do
                case "$FirstWordOfLineInInstallActions" in
                    configure)    PACKAGE_BSYSTEM=configure ; break ;;
                    cmakew)       PACKAGE_BSYSTEM=cmake ; break ;;
                    xmakew)       PACKAGE_BSYSTEM=xmake ; break ;;
                    mesonw)       PACKAGE_BSYSTEM=meson ; break ;;
                    gmakew)       PACKAGE_BSYSTEM=gmake ; break ;;
                    cargow)       PACKAGE_BSYSTEM=cargo ; break ;;
                    go|gow)       PACKAGE_BSYSTEM=go    ; break ;;
                    waf)          PACKAGE_BSYSTEM=waf   ; break ;;
                    zig)          PACKAGE_BSYSTEM=zig   ; break ;;
                    cabal_v2_install)
                                  PACKAGE_BSYSTEM=cabal ; break ;;
                esac
            done
        fi
    fi

    PACKAGE_BSYSTEM_MASTER="${PACKAGE_BSYSTEM%%' '*}"

    #########################################################################################

    for BSTSTEM in $PACKAGE_BSYSTEM
    do
        case $BSTSTEM in
            autogen)     PACKAGE_USE_BSYSTEM_AUTOGENSH=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            autotools)   PACKAGE_USE_BSYSTEM_AUTOTOOLS=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            configure)   PACKAGE_USE_BSYSTEM_CONFIGURE=1 ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            cmake+gmake) PACKAGE_USE_BSYSTEM_CMAKE=1     ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            cmake+ninja) PACKAGE_USE_BSYSTEM_CMAKE=1     ; PACKAGE_USE_BSYSTEM_NINJA=1 ;;
            cmake)       PACKAGE_USE_BSYSTEM_CMAKE=1     ; PACKAGE_USE_BSYSTEM_NINJA=1 ;;
            xmake)       PACKAGE_USE_BSYSTEM_XMAKE=1     ;;
            meson)       PACKAGE_USE_BSYSTEM_MESON=1     ; PACKAGE_USE_BSYSTEM_NINJA=1 ;;
            ninja)       PACKAGE_USE_BSYSTEM_NINJA=1     ;;
            gmake)       PACKAGE_USE_BSYSTEM_GMAKE=1     ;;
            netsurf)     PACKAGE_USE_BSYSTEM_GMAKE=1     ; PACKAGE_USE_BSYSTEM_NETSURF=1 ;;
            rake)        PACKAGE_USE_BSYSTEM_RAKE=1      ;;
            cargo)       PACKAGE_USE_BSYSTEM_CARGO=1     ;;
            cabal)       PACKAGE_USE_BSYSTEM_CABAL=1     ; PACKAGE_USE_BSYSTEM_GMAKE=1 ;;
            go)          PACKAGE_USE_BSYSTEM_GO=1        ;;
            gn)          PACKAGE_USE_BSYSTEM_GN=1        ; PACKAGE_USE_BSYSTEM_NINJA=1 ;;
            waf)         PACKAGE_USE_BSYSTEM_WAF=1       ;;
            zig)         PACKAGE_USE_BSYSTEM_ZIG=1       ;;
            zig@[0-9].[0-9][0-9])
                         PACKAGE_USE_BSYSTEM_ZIG=1       ;;
        esac
    done

    #########################################################################################

    [ -z "$PACKAGE_DOBUILD" ] && {
        case $PACKAGE_BSYSTEM_MASTER in
            autogen)   PACKAGE_DOBUILD='configure' ;;
            autotools) PACKAGE_DOBUILD='configure' ;;
            configure) PACKAGE_DOBUILD='configure' ;;
            netsurf)   PACKAGE_DOBUILD='netsurf_buildsystem' ;;
            cmake*)    PACKAGE_DOBUILD='cmakew' ;;
            xmake)     PACKAGE_DOBUILD='xmakew' ;;
            meson)     PACKAGE_DOBUILD='mesonw' ;;
            ninja)     PACKAGE_DOBUILD='ninjaw clean && ninjaw && ninjaw install' ;;
            gmake)     PACKAGE_DOBUILD='gmakew clean && gmakew && gmakew install' ;;
            cargo)     PACKAGE_DOBUILD='cargow install' ;;
            cabal)     PACKAGE_DOBUILD='cabal_v2_install' ;;
            go)        PACKAGE_DOBUILD='gow' ;;
            gn)        PACKAGE_DOBUILD='gnw' ;;
            waf)       PACKAGE_DOBUILD='waf' ;;
            zig)       PACKAGE_DOBUILD='zig' ;;
            zig@[0-9].[0-9][0-9])
                       PACKAGE_DOBUILD='zig' ;;
        esac
    }

    #########################################################################################

    if [ -n "$PACKAGE_FIX_URL" ] || [ -n "$PACKAGE_PATCHES" ] ; then
        PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP patch"
    fi

    [ -n "$PACKAGE_DEP_PYM" ]                && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3"
    [ -n "$PACKAGE_DEP_PLM" ]                && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl gmake"

    [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP automake"
    [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP automake"
    [ "$PACKAGE_USE_BSYSTEM_CONFIGURE" = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake"
    [ "$PACKAGE_USE_BSYSTEM_NETSURF"   = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake netsurf_buildsystem"
    [ "$PACKAGE_USE_BSYSTEM_MESON"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3"
    [ "$PACKAGE_USE_BSYSTEM_MESON"     = 1 ] && PACKAGE_DEP_PYM="$PACKAGE_DEP_PYM meson"
    [ "$PACKAGE_USE_BSYSTEM_CMAKE"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP cmake"
    [ "$PACKAGE_USE_BSYSTEM_GMAKE"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP gmake"
    [ "$PACKAGE_USE_BSYSTEM_XMAKE"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP xmake"
    [ "$PACKAGE_USE_BSYSTEM_NINJA"     = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ninja"
    [ "$PACKAGE_USE_BSYSTEM_RAKE"      = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ruby"
    [ "$PACKAGE_USE_BSYSTEM_GO"        = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP golang"
    [ "$PACKAGE_USE_BSYSTEM_WAF"       = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP python3"
    [ "$PACKAGE_USE_BSYSTEM_ZIG"       = 1 ] && PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP $PACKAGE_BSYSTEM"

    [ "$PACKAGE_USE_BSYSTEM_CABAL"     = 1 ] && PACKAGE_DEP_PKG="$PACKAGE_DEP_PKG libncurses libffi libz"

    #########################################################################################

    [ "$PACKAGE_USE_BSYSTEM_WAF"   = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_ZIG"   = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_GO"    = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_CABAL" = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_XMAKE" = 1 ] && PACKAGE_BINBSTD=1
    [ "$PACKAGE_USE_BSYSTEM_NETSURF" = 1 ] && PACKAGE_BINBSTD=1

    if [ -z  "$PACKAGE_BINBSTD" ] ; then
        if [ "$PACKAGE_BSYSTEM_MASTER" = gmake ] ; then
            PACKAGE_BINBSTD=1
        else
            PACKAGE_BINBSTD=0
        fi
    fi

    #########################################################################################

    if [ -z "$PACKAGE_PKGTYPE" ] ; then
        case $PACKAGE_NAME in
            lib*)   PACKAGE_PKGTYPE=lib ;;
            *lib)   PACKAGE_PKGTYPE=lib ;;
            *-dev)  PACKAGE_PKGTYPE=lib ;;
            xorg-lib*)
                    PACKAGE_PKGTYPE=lib ;;
               *)   PACKAGE_PKGTYPE=exe ;;
        esac
    fi

    #########################################################################################

    [ -z "$PACKAGE_LTOABLE" ] && PACKAGE_LTOABLE=1
    [ -z "$PACKAGE_MOVABLE" ] && PACKAGE_MOVABLE=1
    [ -z "$PACKAGE_SUPPORT_BUILD_IN_PARALLEL" ] && PACKAGE_SUPPORT_BUILD_IN_PARALLEL=1
    [ -z "$PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" ] && PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=1

    #########################################################################################

    PACKAGE_DEP_UPP="${PACKAGE_DEP_UPP#' '}"
}

# }}}
##############################################################################
# {{{ operations of receipt

# __generate_receipt_of_the_given_package <PACKAGE-NAME>
  __generate_receipt_of_the_given_package() {
    [ -z "$1" ] && {
        error "__generate_receipt_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified."
        return 1
    }

    cp "$PACKAGE_FORMULA_FILEPATH" "$PACKAGE_RECEIPT_FILEPATH"

    gsed -i '/^#src-url: dir:/d' "$PACKAGE_RECEIPT_FILEPATH"

    gsed -i "1i pkgname: $PACKAGE_NAME" "$PACKAGE_RECEIPT_FILEPATH"

    grep -q '^pkgtype: ' "$PACKAGE_RECEIPT_FILEPATH" || gsed -i "/^pkgname:/a pkgtype: $PACKAGE_PKGTYPE" "$PACKAGE_RECEIPT_FILEPATH"
    grep -q '^version: ' "$PACKAGE_RECEIPT_FILEPATH" || gsed -i "/^pkgtype:/a version: $PACKAGE_VERSION" "$PACKAGE_RECEIPT_FILEPATH"
    grep -q '^web-url: ' "$PACKAGE_RECEIPT_FILEPATH" || gsed -i "/^summary:/a web-url: $PACKAGE_GIT_URL" "$PACKAGE_RECEIPT_FILEPATH"
    grep -q '^git-url: ' "$PACKAGE_RECEIPT_FILEPATH" || gsed -i "/^web-url:/a git-url: $PACKAGE_GIT_URL" "$PACKAGE_RECEIPT_FILEPATH"
    grep -q '^bsystem: ' "$PACKAGE_RECEIPT_FILEPATH" || gsed -i "/^install:/i bsystem: $PACKAGE_BSYSTEM" "$PACKAGE_RECEIPT_FILEPATH"
    grep -q '^binbstd: ' "$PACKAGE_RECEIPT_FILEPATH" || gsed -i "/^bsystem:/a binbstd: $PACKAGE_BINBSTD" "$PACKAGE_RECEIPT_FILEPATH"

    [ -n "$PACKAGE_GIT_SHA" ] && {
        grep -q '^git-sha: ' "$PACKAGE_RECEIPT_FILEPATH" || {
            gsed -i "/^git-url:/a git-sha: $PACKAGE_GIT_SHA" "$PACKAGE_RECEIPT_FILEPATH"
        }

        grep -q '^git-sha: ' "$PACKAGE_RECEIPT_FILEPATH" || {
            gsed -i "3i git-sha: $PACKAGE_GIT_SHA" "$PACKAGE_RECEIPT_FILEPATH"
        }
    }

    [ -n "$PACKAGE_DEP_UPP" ] && {
        if grep -q '^dep-upp: ' "$PACKAGE_RECEIPT_FILEPATH" ; then
            gsed -i "/^dep-upp: /c dep-upp: $PACKAGE_DEP_UPP" "$PACKAGE_RECEIPT_FILEPATH"
        else
            gsed -i "/^bsystem: /i dep-upp: $PACKAGE_DEP_UPP" "$PACKAGE_RECEIPT_FILEPATH"
        fi
    }

    cat >> "$PACKAGE_RECEIPT_FILEPATH" <<EOF
builtby: xcpkg-$XCPKG_VERSION
builtat: $TIMESTAMP_UNIX
buildon:
    os-arch: $NATIVE_PLATFORM_ARCH
    os-kind: $NATIVE_PLATFORM_KIND
    os-type: $NATIVE_PLATFORM_TYPE
    os-name: $NATIVE_PLATFORM_NAME
    os-vers: $NATIVE_PLATFORM_VERS
    os-ncpu: $NATIVE_PLATFORM_NCPU
    os-euid: $NATIVE_PLATFORM_EUID
    os-egid: $NATIVE_PLATFORM_EGID
builtfor: $TARGET_PLATFORM_SPEC
profile: $PROFILE
EOF
}


# __load_receipt_of_the_given_package <PACKAGE-NAME|PACKAGE-SPEC>
  __load_receipt_of_the_given_package() {
    PACKAGE_SPEC=
    PACKAGE_SPEC="$(inspect_package_spec "$1")"

    is_package_installed "$PACKAGE_SPEC" || return $?

    PACKAGE_INSTALLED_DIR="$(readlink -f "$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC")"

    PACKAGE_RECEIPT_FILEPATH="$PACKAGE_INSTALLED_DIR/.xcpkg/RECEIPT.yml"

    unset RECEIPT_PACKAGE_PKGNAME
    unset RECEIPT_PACKAGE_PKGTYPE

    unset RECEIPT_PACKAGE_PROFILE

    unset RECEIPT_PACKAGE_SUMMARY
    unset RECEIPT_PACKAGE_VERSION
    unset RECEIPT_PACKAGE_LICENSE

    unset RECEIPT_PACKAGE_WEB_URL

    unset RECEIPT_PACKAGE_GIT_URL
    unset RECEIPT_PACKAGE_GIT_SHA
    unset RECEIPT_PACKAGE_GIT_REF
    unset RECEIPT_PACKAGE_GIT_NTH

    unset RECEIPT_PACKAGE_SRC_URL
    unset RECEIPT_PACKAGE_SRC_URI
    unset RECEIPT_PACKAGE_SRC_SHA

    unset RECEIPT_PACKAGE_FIX_URL
    unset RECEIPT_PACKAGE_FIX_URI
    unset RECEIPT_PACKAGE_FIX_SHA
    unset RECEIPT_PACKAGE_FIX_OPT

    unset RECEIPT_PACKAGE_RES_URL
    unset RECEIPT_PACKAGE_RES_URI
    unset RECEIPT_PACKAGE_RES_SHA

    unset RECEIPT_PACKAGE_PATCHES
    unset RECEIPT_PACKAGE_RESLIST

    unset RECEIPT_PACKAGE_DEP_PKG
    unset RECEIPT_PACKAGE_DEP_LIB
    unset RECEIPT_PACKAGE_DEP_UPP
    unset RECEIPT_PACKAGE_DEP_PYM
    unset RECEIPT_PACKAGE_DEP_PLM

    unset RECEIPT_PACKAGE_BSYSTEM
    unset RECEIPT_PACKAGE_BSCRIPT

    unset RECEIPT_PACKAGE_MOVABLE
    unset RECEIPT_PACKAGE_LTOABLE
    unset RECEIPT_PACKAGE_DOEXTRA

    unset RECEIPT_PACKAGE_DOFETCH
    unset RECEIPT_PACKAGE_DO12345
    unset RECEIPT_PACKAGE_DOPATCH
    unset RECEIPT_PACKAGE_PREPARE
    unset RECEIPT_PACKAGE_DOBUILD
    unset RECEIPT_PACKAGE_DOTWEAK

    unset RECEIPT_PACKAGE_BINDENV
    unset RECEIPT_PACKAGE_CAVEATS

    unset RECEIPT_PACKAGE_BUILTBY
    unset RECEIPT_PACKAGE_BUILTAT

    unset RECEIPT_PACKAGE_BUILTFOR
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_VERS
    unset RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH

    unset RECEIPT_PACKAGE_SUPPORT_BUILD_IN_PARALLEL
    unset RECEIPT_PACKAGE_DEVELOPER

    #########################################################################################

    RECEIPT_PACKAGE_PKGNAME="$(yq '.pkgname | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PKGTYPE="$(yq '.pkgtype | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_PROFILE="$(yq '.profile | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_SUMMARY="$(yq '.summary | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_LICENSE="$(yq '.license | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_VERSION="$(yq '.version | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_WEB_URL="$(yq '.web-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_GIT_URL="$(yq '.git-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_GIT_SHA="$(yq '.git-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_GIT_REF="$(yq '.git-ref | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_GIT_NTH="$(yq '.git-nth | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_SRC_URL="$(yq '.src-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_SRC_URI="$(yq '.src-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_SRC_SHA="$(yq '.src-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_FIX_URL="$(yq '.fix-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_FIX_URI="$(yq '.fix-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_FIX_SHA="$(yq '.fix-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_FIX_OPT="$(yq '.fix-opt | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_RES_URL="$(yq '.res-url | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_RES_URI="$(yq '.res-uri | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_RES_SHA="$(yq '.res-sha | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_RESLIST="$(yq '.reslist | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PATCHES="$(yq '.patches | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_DEP_PKG="$(yq '.dep-pkg | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_LIB="$(yq '.dep-lib | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_UPP="$(yq '.dep-upp | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_PYM="$(yq '.dep-pip | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DEP_PLM="$(yq '.dep-plm | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BSYSTEM="$(yq '.bsystem | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_BSCRIPT="$(yq '.bscript | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_BINBSTD="$(yq '.binbstd | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_CCFLAGS="$(yq '.ccflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_XXFLAGS="$(yq '.xxflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PPFLAGS="$(yq '.ppflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_LDFLAGS="$(yq '.ldflags | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_MOVABLE="$(yq '.movable | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_LTOABLE="$(yq '.ltoable | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DOEXTRA="$(yq '.doextra | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_DOFETCH="$(yq '.dofetch | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DO12345="$(yq '.do12345 | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DOPATCH="$(yq '.dopatch | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_PREPARE="$(yq '.prepare | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DOBUILD="$(yq '.install | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_DOTWEAK="$(yq '.dotweak | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BINDENV="$(yq '.bindenv | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_CAVEATS="$(yq '.caveats | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BUILTBY="$(yq '.builtby | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"
    RECEIPT_PACKAGE_BUILTAT="$(yq '.builtat | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_BUILTFOR="$(yq '.builtfor | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    RECEIPT_PACKAGE_DEVELOPER="$(yq '.developer | select(. != null)' "$PACKAGE_RECEIPT_FILEPATH")"

    #########################################################################################

    [ -z "$RECEIPT_PACKAGE_PKGNAME" ] && abort 1 "receipt scheme error. pkgname mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_PKGTYPE" ] && abort 1 "receipt scheme error. pkgtype mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_VERSION" ] && abort 1 "receipt scheme error. version mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_SUMMARY" ] && abort 1 "receipt scheme error. summary mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_WEB_URL" ] && abort 1 "receipt scheme error. web-url mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_BUILTBY" ] && abort 1 "receipt scheme error. builtby mapping was not found in $PACKAGE_RECEIPT_FILEPATH."
    [ -z "$RECEIPT_PACKAGE_BUILTAT" ] && abort 1 "receipt scheme error. builtat mapping was not found in $PACKAGE_RECEIPT_FILEPATH."

    [ "${#RECEIPT_PACKAGE_BUILTAT}" -eq 10 ] || abort 1 "receipt scheme error. builtat mapping's value length must be 10."

    if [ "${PACKAGE_SPEC#*/}" != "$RECEIPT_PACKAGE_PKGNAME" ] ; then
        error "$PACKAGE_RECEIPT_FILEPATH is broken. value of RECEIPT_PACKAGE_PKGNAME does not identical with your request: ${PACKAGE_SPEC#*/}"
        return 1
    fi

    if [ "${PACKAGE_SPEC%/*}" != "$RECEIPT_PACKAGE_BUILTFOR" ] ; then
        error "$PACKAGE_RECEIPT_FILEPATH is broken. value of RECEIPT_PACKAGE_BUILTFOR does not identical with your request: ${PACKAGE_SPEC%/*}"
        return 1
    fi

    #########################################################################################

    RECEIPT_PACKAGE_BUILTFOR_PLATFORM="$RECEIPT_PACKAGE_BUILTFOR"

    RECEIPT_PACKAGE_BUILTFOR_PLATFORM_NAME="$(printf '%s\n' "$RECEIPT_PACKAGE_BUILTFOR" | cut -d- -f1)"
    RECEIPT_PACKAGE_BUILTFOR_PLATFORM_VERS="$(printf '%s\n' "$RECEIPT_PACKAGE_BUILTFOR" | cut -d- -f2)"
    RECEIPT_PACKAGE_BUILTFOR_PLATFORM_ARCH="$(printf '%s\n' "$RECEIPT_PACKAGE_BUILTFOR" | cut -d- -f3)"
}

# }}}
##############################################################################
# {{{ operations of manifest

# __generate_manifest_of_the_given_package <PACKAGE-NAME>
  __generate_manifest_of_the_given_package() {
    # fuck, some package's filename has space
    export IFS='
'

    exec 7> "$PACKAGE_MANIFEST_FILEPATH"

    for dirname in $(find -mindepth 1 -maxdepth 1 -type d -not -name .xcpkg -printf '%P\n')
    do
        for item in $(find "$dirname" -printf '%y:%p\n')
        do
            X=$(printf '%s\n' "$item" | cut -c1)
            Y=${item#$X:}

            case $X in
                l)  if [ -d "$Y" ] ; then
                        printf 'D|0000000000000000000000000000000000000000000000000000000000000000|%s/\n' "$Y" >&7
                    else
                        printf 'l|%s|%s\n' "$(sha256sum "$Y" | cut -d ' ' -f1)"                           "$Y" >&7
                    fi
                    ;;
                d)  printf 'd|0000000000000000000000000000000000000000000000000000000000000000|%s/\n' "$Y" >&7 ;;
                *)  printf '%s|%s|%s\n' "$X" "$(sha256sum "$Y" | cut -d ' ' -f1)"                     "$Y" >&7 ;;
            esac
        done
    done

    exec 7>&-

    unset IFS
}

# }}}
##############################################################################
# {{{ xcpkg is-available

# check if the given package is available
# if the version condition is given, check if the condition is matched
#
# condition operator:
# eq  equal
# ne  not equal
# gt  greater than
# lt  less than
# ge  greater than or equal
# le  less than or equal
#
# examples:
# is_package_available automake eq 1.16.0
# is_package_available automake lt 1.16.0
# is_package_available automake gt 1.16.0
# is_package_available automake le 1.16.0
# is_package_available automake ge 1.16.0
# is_package_available automake
is_package_available() {
    case $# in
        0)  abort 1 "package name is unspecified." ;;
        1)  [ -n "$(__path_of_formula_of_the_given_package "$1")" ] ;;
        3)  __load_formula_of_the_given_package "$1"
            shift
            version_match "$PACKAGE_VERSION" "$@"
            ;;
        *)  abort 1 "is available command only accept 1 or 3 argument."
    esac
}

# }}}
##############################################################################
# {{{ xcpkg is-installed

# is_package_installed <PACKAGE-SPEC>
  is_package_installed() {
    (
        PACKAGE_INSTALL_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$1"

        [ -L "$PACKAGE_INSTALL_DIR" ] || exit 11
        [ -d "$PACKAGE_INSTALL_DIR" ] || exit 12
        [ -f "$PACKAGE_INSTALL_DIR/.xcpkg/MANIFEST.txt" ] || exit 14
        [ -f "$PACKAGE_INSTALL_DIR/.xcpkg/RECEIPT.yml" ]  || exit 15
    )
}

# }}}
##############################################################################
# {{{ xcpkg is-outdated

# is_package__outdated <PACKAGE-SPEC>
  is_package__outdated() {
    __load_receipt_of_the_given_package "$1"
    __load_formula_of_the_given_package "$RECEIPT_PACKAGE_PKGNAME"
    version_match "$PACKAGE_VERSION" gt "$RECEIPT_PACKAGE_VERSION"
}

# }}}
##############################################################################
# {{{ xcpkg ls-available [-v] [--yaml | --json]

__list_available_packages() {
    unset OUTPUT_MODE
    unset OUTPUT_TYPE

    for arg in $@
    do
        case $arg in
            -v)     OUTPUT_MODE=full ;;
            --json) OUTPUT_TYPE=json ;;
            --yaml) OUTPUT_TYPE=yaml ;;
            *) abort 1 "unrecognized argument: $arg"
        esac
    done

    if [ -z "$OUTPUT_MODE" ] ; then
        __list_available_package_names
    else
        AVAILABLE_PACKAGE_NAMES="$(__list_available_package_names)"

        [ -z "$AVAILABLE_PACKAGE_NAMES" ] && return 0

        IS_FIRST_ELEMENT=1

        case $OUTPUT_TYPE in
            yaml|'')
                for PKGNAME in $AVAILABLE_PACKAGE_NAMES
                do
                    if [ "$IS_FIRST_ELEMENT" = 1 ] ; then
                        unset IS_FIRST_ELEMENT
                    else
                        printf '%s\n' '---'
                    fi
                    __info_the_given_available_package_as_yaml "$PKGNAME"
                done
                ;;
            json)
                printf '%s\n' '['

                for PKGNAME in $AVAILABLE_PACKAGE_NAMES
                do
                    if [ "$IS_FIRST_ELEMENT" = 1 ] ; then
                        unset IS_FIRST_ELEMENT
                    else
                        printf '%s\n' ','
                    fi
                    __info_the_given_available_package_as_json "$PKGNAME"
                done

                printf '%s\n' ']'
                ;;
        esac
    fi
}

__list_available_package_names() {
    [ -d "$XCPKG_FORMULA_REPO_ROOT" ] || return 0

    {
        FORMULA_REPOSITORY_NAMES=

        for item in $(cd "$XCPKG_FORMULA_REPO_ROOT" && ls)
        do
            if [ -f "$XCPKG_FORMULA_REPO_ROOT/$item/.xcpkg-formula-repo.yml" ] ; then
                FORMULA_REPOSITORY_NAMES="$FORMULA_REPOSITORY_NAMES $item"
            fi
        done

        for FORMULA_REPOSITORY_NAME in $FORMULA_REPOSITORY_NAMES
        do
            FORMULA_SEARCH_DIR="$XCPKG_FORMULA_REPO_ROOT/$FORMULA_REPOSITORY_NAME/formula"

            if [ -d  "$FORMULA_SEARCH_DIR" ] ; then
                find "$FORMULA_SEARCH_DIR" -maxdepth 1 -type f -name '*.yml' -exec basename {} .yml \; || return 1
            fi
        done
    } | sort | uniq
}

# }}}
##############################################################################
# {{{ xcpkg ls-installed

__list_installed_packages() {
    if [ -d "$XCPKG_PACKAGE_INSTALLED_ROOT" ] ; then
         cd "$XCPKG_PACKAGE_INSTALLED_ROOT" || return 1
        find . -maxdepth 2 -mindepth 2 -type l -regex '\./\(DriverKit\|MacOSX\|AppleTVOS\|AppleTVSimulator\|iPhoneOS\|iPhoneSimulator\|WatchOS\|WatchSimulator\)-[^-]*-[^-]*/.*' -printf '%P\n'
    else
        return 0
    fi
}

# }}}
##############################################################################
# {{{ xcpkg ls-outdated

__list__outdated_packages() {
    for PACKAGE_SPEC in $(__list_installed_packages)
    do
        if is_package__outdated "$PACKAGE_SPEC" ; then
            printf '%s\n' "$PACKAGE_SPEC"
        fi
    done
}

# }}}
##############################################################################
# {{{ xcpkg search <REGULAR-EXPRESSION-PATTERN> [-v]

__search_packages() {
    [ -z "$1" ] && abort 1 "please specify a regular express partten."

    AVAILABLE_PACKAGE_NAMES_ALL="$(__list_available_package_names)"

    [ -z "$AVAILABLE_PACKAGE_NAMES_ALL" ] && return 0

    AVAILABLE_PACKAGE_NAMES_FILTERED="$(printf '%s\n' $AVAILABLE_PACKAGE_NAMES_ALL | grep "$1" || true)"

    [ -z "$AVAILABLE_PACKAGE_NAMES_FILTERED" ] && return 0

    case $2 in
        '') printf '%s\n' $AVAILABLE_PACKAGE_NAMES_FILTERED ;;
        -v) IS_FIRST_ELEMENT=1

            for PKGNAME in $AVAILABLE_PACKAGE_NAMES_FILTERED
            do
                if [ "$IS_FIRST_ELEMENT" = 1 ] ; then
                    unset IS_FIRST_ELEMENT
                else
                    printf '%s\n' '---'
                fi

                __info_the_given_available_package_as_yaml "$PKGNAME"
            done
            ;;
        *)  abort 1 "unrecognzied argument: $2"
    esac
}

# }}}
##############################################################################
# {{{ xcpkg info

# __info_the_given_available_package_as_json <PACKAGE-NAME>
  __info_the_given_available_package_as_json() {
    __load_formula_of_the_given_package "$1"

    if [ -z "$PACKAGE_WEB_URL" ] ; then
        PACKAGE_WEB_URL="$PACKAGE_GIT_URL"
    fi

    jq  --null-input \
        --arg pkgname "$PACKAGE_NAME" \
        --arg pkgtype "$PACKAGE_PKGTYPE" \
        --arg version "$PACKAGE_VERSION" \
        --arg summary "$PACKAGE_SUMMARY" \
        --arg license "$PACKAGE_LICENSE" \
        --arg web_url "$PACKAGE_WEB_URL" \
        --arg git_url "$PACKAGE_GIT_URL" \
        --arg git_sha "$PACKAGE_GIT_SHA" \
        --arg git_ref "$PACKAGE_GIT_REF" \
        --arg git_nth "$PACKAGE_GIT_NTH" \
        --arg src_url "$PACKAGE_SRC_URL" \
        --arg src_uri "$PACKAGE_SRC_URI" \
        --arg src_sha "$PACKAGE_SRC_SHA" \
        --arg fix_url "$PACKAGE_FIX_URL" \
        --arg fix_uri "$PACKAGE_FIX_URI" \
        --arg fix_sha "$PACKAGE_FIX_SHA" \
        --arg res_url "$PACKAGE_RES_URL" \
        --arg res_uri "$PACKAGE_RES_URI" \
        --arg res_sha "$PACKAGE_RES_SHA" \
        --arg patches "$PACKAGE_PATCHES" \
        --arg reslist "$PACKAGE_RESLIST" \
        --arg dep_pkg "$PACKAGE_DEP_PKG" \
        --arg dep_lib "$PACKAGE_DEP_LIB" \
        --arg dep_upp "$PACKAGE_DEP_UPP" \
        --arg dep_pip "$PACKAGE_DEP_PYM" \
        --arg dep_plm "$PACKAGE_DEP_PLM" \
        --arg movable "$PACKAGE_MOVABLE" \
        --arg ltoable "$PACKAGE_LTOABLE" \
        --arg dofetch "$PACKAGE_DOFETCH" \
        --arg do12345 "$PACKAGE_DO12345" \
        --arg dopatch "$PACKAGE_DOPATCH" \
        --arg prepare "$PACKAGE_PREPARE" \
        --arg install "$PACKAGE_DOBUILD" \
        --arg doextra "$PACKAGE_DOEXTRA" \
        --arg dotweak "$PACKAGE_DOTWEAK" \
        --arg bindenv "$PACKAGE_BINDENV" \
        --arg caveats "$PACKAGE_CAVEATS" \
        --arg bsystem "$PACKAGE_BSYSTEM" \
        --arg binbstd "$PACKAGE_BINBSTD" \
        --arg ccflags "$PACKAGE_CCFLAGS" \
        --arg xxflags "$PACKAGE_XXFLAGS" \
        --arg ppflags "$PACKAGE_PPFLAGS" \
        --arg ldflags "$PACKAGE_LDFLAGS" \
        --arg developer "$PACKAGE_DEVELOPER" \
'{
    "pkgname":$pkgname,
    "pkgtype":$pkgtype,
    "version":$version,
    "license":$license,
    "summary":$summary,
    "web-url":$web_url,
    "git-url":$git_url,
    "git-sha":$git_sha,
    "git-ref":$git_ref,
    "git-nth":$git_nth,
    "src-url":$src_url,
    "src-uri":$src_uri,
    "src-sha":$src_sha,
    "fix-url":$fix_url,
    "fix-uri":$fix_uri,
    "fix-sha":$fix_sha,
    "res-url":$res_url,
    "res-uri":$res_uri,
    "res-sha":$res_sha,
    "patches":$patches,
    "reslist":$reslist,
    "dep-pkg":$dep_pkg,
    "dep-lib":$dep_lib,
    "dep-upp":$dep_upp,
    "dep-pip":$dep_pip,
    "dep-plm":$dep_plm,
    "bsystem":$bsystem,
    "binbstd":$binbstd,
    "ccflags":$ccflags,
    "xxflags":$xxflags,
    "ppflags":$ppflags,
    "ldflags":$ldflags,
    "developer":$developer,
    "movable":$movable,
    "ltoable":$ltoable,
    "dofetch":$dofetch,
    "do12345":$do12345,
    "dopatch":$dopatch,
    "prepare":$prepare,
    "install":$install,
    "doextra":$doextra,
    "dotweak":$dotweak,
    "dotweak":$dotweak,
    "bindenv":$bindenv,
    "caveats":$caveats
}' | jq 'with_entries(select(.value != ""))'
}

# __info_the_given_available_package_as_yaml <PACKAGE-NAME>
  __info_the_given_available_package_as_yaml() {
    __load_formula_of_the_given_package "$1"

    if [ -z "$PACKAGE_WEB_URL" ] ; then
        PACKAGE_WEB_URL="$PACKAGE_GIT_URL"
    fi

    if is_package_installed "$1" ; then
        PACKAGE_INSTALLED=yes
    else
        PACKAGE_INSTALLED=no
    fi

    {
    cat <<EOF
pkgname: $PACKAGE_NAME
pkgtype: $PACKAGE_PKGTYPE
version: $PACKAGE_VERSION
license: $PACKAGE_LICENSE
summary: $PACKAGE_SUMMARY
web-url: $PACKAGE_WEB_URL
git-url: $PACKAGE_GIT_URL
git-sha: $PACKAGE_GIT_SHA
git-ref: $PACKAGE_GIT_REF
git-nth: $PACKAGE_GIT_NTH
src-url: $PACKAGE_SRC_URL
src-uri: $PACKAGE_SRC_URI
src-sha: $PACKAGE_SRC_SHA
fix-url: $PACKAGE_FIX_URL
fix-uri: $PACKAGE_FIX_URI
fix-sha: $PACKAGE_FIX_SHA
res-url: $PACKAGE_RES_URL
res-uri: $PACKAGE_RES_URI
res-sha: $PACKAGE_RES_SHA
dep-pkg: $PACKAGE_DEP_PKG
dep-lib: $PACKAGE_DEP_LIB
dep-upp: $PACKAGE_DEP_UPP
dep-pip: $PACKAGE_DEP_PYM
dep-plm: $PACKAGE_DEP_PLM
bsystem: $PACKAGE_BSYSTEM
binbstd: $PACKAGE_BINBSTD
ppflags: $PACKAGE_PPFLAGS
ccflags: $PACKAGE_CCFLAGS
xxflags: $PACKAGE_XXFLAGS
ldflags: $PACKAGE_LDFLAGS
installed: $PACKAGE_INSTALLED
EOF
    } | yq eval '. | with_entries(select(.value != null))'
}

# __info_the_given_available_package_as_shell <PACKAGE-NAME>
  __info_the_given_available_package_as_shell() {
    __load_formula_of_the_given_package "$1"

    while read KEY
    do
        printf "%s='%s'\n" "${PACKAGE_NAME_UPPERCASE_UNDERSCORE}_${KEY}" "$(eval echo \$$KEY)"
    done <<EOF
PACKAGE_NAME
PACKAGE_PKGTYPE
PACKAGE_SUMMARY
PACKAGE_LICENSE
PACKAGE_VERSION
PACKAGE_VERSION_MAJOR
PACKAGE_VERSION_MINOR
PACKAGE_VERSION_PATCH
PACKAGE_VERSION_TWEAK
PACKAGE_WEB_URL
PACKAGE_GIT_URL
PACKAGE_GIT_SHA
PACKAGE_GIT_REF
PACKAGE_GIT_NTH
PACKAGE_SRC_URL
PACKAGE_SRC_URI
PACKAGE_SRC_SHA
PACKAGE_SRC_FILETYPE
PACKAGE_SRC_FILENAME
PACKAGE_SRC_FILEPATH
PACKAGE_FIX_URL
PACKAGE_FIX_URI
PACKAGE_FIX_SHA
PACKAGE_FIX_FILETYPE
PACKAGE_FIX_FILENAME
PACKAGE_FIX_FILEPATH
PACKAGE_RES_URL
PACKAGE_RES_URI
PACKAGE_RES_SHA
PACKAGE_RES_FILETYPE
PACKAGE_RES_FILENAME
PACKAGE_RES_FILEPATH
PACKAGE_BSCRIPT
PACKAGE_BSYSTEM
PACKAGE_BINBSTD
PACKAGE_USE_BSYSTEM_GO
PACKAGE_USE_BSYSTEM_RAKE
PACKAGE_USE_BSYSTEM_NINJA
PACKAGE_USE_BSYSTEM_GMAKE
PACKAGE_USE_BSYSTEM_CMAKE
PACKAGE_USE_BSYSTEM_XMAKE
PACKAGE_USE_BSYSTEM_MESON
PACKAGE_USE_BSYSTEM_CARGO
PACKAGE_USE_BSYSTEM_CABAL
PACKAGE_USE_BSYSTEM_AUTOGENSH
PACKAGE_USE_BSYSTEM_AUTOTOOLS
PACKAGE_USE_BSYSTEM_CONFIGURE
PACKAGE_DEP_PKG
PACKAGE_DEP_LIB
PACKAGE_DEP_UPP
PACKAGE_DEP_PYM
PACKAGE_DEP_PLM
PACKAGE_CCFLAGS
PACKAGE_XXFLAGS
PACKAGE_PPFLAGS
PACKAGE_LDFLAGS
PACKAGE_FORMULA_FILEPATH
PACKAGE_SUPPORT_BUILD_IN_PARALLEL
PACKAGE_DEVELOPER
EOF
}

# __info_the_given_available_package <PACKAGE-NAME> [--yaml] [--json] [<KEY>]
# __info_the_given_available_package curl
# __info_the_given_available_package curl version
# __info_the_given_available_package curl web-url
  __info_the_given_available_package() {
    case $2 in
        --yaml|'')
            __info_the_given_available_package_as_yaml "$1"
            ;;
        --json)
            __info_the_given_available_package_as_json "$1"
            ;;
        movable)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_MOVABLE"
            ;;
        ltoable)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_LTOABLE"
            ;;
        dofetch)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOFETCH"
            ;;
        do12345)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DO12345"
            ;;
        dopatch)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOPATCH"
            ;;
        prepare)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_PREPARE"
            ;;
        install)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOBUILD"
            ;;
        doextra)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOEXTRA"
            ;;
        dotweak)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DOTWEAK"
            ;;
        bindenv)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_BINDENV"
            ;;
        caveats)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_CAVEATS"
            ;;
        developer)
            __load_formula_of_the_given_package "$1"
            printf '%s\n' "$PACKAGE_DEVELOPER"
            ;;
        src-ft)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_SRC_FILETYPE" ] ; then
                printf '%s\n' "$PACKAGE_SRC_FILETYPE"
            fi
            ;;
        src-fp)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_SRC_FILEPATH" ] ; then
                printf '%s\n' "$PACKAGE_SRC_FILEPATH"
            fi
            ;;
        fix-ft)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_FIX_FILETYPE" ] ; then
                printf '%s\n' "$PACKAGE_FIX_FILETYPE"
            fi
            ;;
        fix-fp)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_FIX_FILEPATH" ] ; then
                printf '%s\n' "$PACKAGE_FIX_FILEPATH"
            fi
            ;;
        res-ft)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_RES_FILETYPE" ] ; then
                printf '%s\n' "$PACKAGE_RES_FILETYPE"
            fi
            ;;
        res-fp)
            __load_formula_of_the_given_package "$1"
            if [ -n "$PACKAGE_RES_FILEPATH" ] ; then
                printf '%s\n' "$PACKAGE_RES_FILEPATH"
            fi
            ;;
        *)  __load_formula_of_the_given_package "$1"
            __PACKAGE_GET__KEY__="$(printf '%s\n' "$2" | tr '+-.' '_' | tr a-z A-Z)"
            eval echo \$PACKAGE_$__PACKAGE_GET__KEY__
    esac
}

# __info_the_given_installed_package <PACKAGE-SPEC> [<KEY>]
# __info_the_given_installed_package curl
# __info_the_given_installed_package curl version
# __info_the_given_installed_package curl web-url
  __info_the_given_installed_package() {
    case $2 in
        --yaml|'')
            PACKAGE_SPEC=
            PACKAGE_SPEC="$(inspect_package_spec "$1")"

            if is_package_installed "$PACKAGE_SPEC" ; then
                yq "$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC/.xcpkg/RECEIPT.yml"
            else
                abort 1 "package '$PACKAGE_SPEC' is not installed."
            fi
            ;;
        --json)
            __info_the_given_installed_package_as_json "$1"
            ;;
        --prefix)
            PACKAGE_SPEC=
            PACKAGE_SPEC="$(inspect_package_spec "$1")"

            if is_package_installed "$PACKAGE_SPEC" ; then
                PACKAGE_INSTALLED_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
                printf '%s\n' "$PACKAGE_INSTALLED_DIR"
            else
                abort 1 "package '$PACKAGE_SPEC' is not installed."
            fi
            ;;
        --files)
            PACKAGE_SPEC=
            PACKAGE_SPEC="$(inspect_package_spec "$1")"

            if is_package_installed "$PACKAGE_SPEC" ; then
                cut -d '|' -f3 "$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC/.xcpkg/MANIFEST.txt"
            else
                abort 1 "package '$PACKAGE_SPEC' is not installed."
            fi
            ;;
        builtat)
            __load_receipt_of_the_given_package "$1"
            printf '%s\n' "$RECEIPT_PACKAGE_BUILTAT"
            ;;
        builtat-rfc-3339)
            __load_receipt_of_the_given_package "$1"
            date -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%d %H:%M:%S%:z'
            ;;
        builtat-iso-8601)
            __load_receipt_of_the_given_package "$1"
            date -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%dT%H:%M:%S%:z'
            ;;
        builtat-rfc-3339-utc)
            __load_receipt_of_the_given_package "$1"
            date -u -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%d %H:%M:%S%:z'
            ;;
        builtat-iso-8601-utc)
            __load_receipt_of_the_given_package "$1"
            date -u -d "@$RECEIPT_PACKAGE_BUILTAT" '+%Y-%m-%dT%H:%M:%SZ'
            ;;
        *)  __load_receipt_of_the_given_package "$1"
            __PACKAGE_GET__KEY__="$(printf '%s\n' "$2" | tr '+-.' '_' | tr a-z A-Z)"
            eval echo \$RECEIPT_PACKAGE_$__PACKAGE_GET__KEY__
    esac
}

# __info_the_given_installed_package_as_json <PACKAGE-NAME|PACKAGE_SPEC>
  __info_the_given_installed_package_as_json() {
    __load_receipt_of_the_given_package "$1"

    jq  --null-input \
        --arg pkgname "$RECEIPT_PACKAGE_PKGNAME" \
        --arg pkgtype "$RECEIPT_PACKAGE_PKGTYPE" \
        --arg version "$RECEIPT_PACKAGE_VERSION" \
        --arg summary "$RECEIPT_PACKAGE_SUMMARY" \
        --arg license "$RECEIPT_PACKAGE_LICENSE" \
        --arg web_url "$RECEIPT_PACKAGE_WEB_URL" \
        --arg git_url "$RECEIPT_PACKAGE_GIT_URL" \
        --arg git_sha "$RECEIPT_PACKAGE_GIT_SHA" \
        --arg git_ref "$RECEIPT_PACKAGE_GIT_REF" \
        --arg git_nth "$RECEIPT_PACKAGE_GIT_NTH" \
        --arg src_url "$RECEIPT_PACKAGE_SRC_URL" \
        --arg src_uri "$RECEIPT_PACKAGE_SRC_URI" \
        --arg src_sha "$RECEIPT_PACKAGE_SRC_SHA" \
        --arg fix_url "$RECEIPT_PACKAGE_FIX_URL" \
        --arg fix_uri "$RECEIPT_PACKAGE_FIX_URI" \
        --arg fix_sha "$RECEIPT_PACKAGE_FIX_SHA" \
        --arg res_url "$RECEIPT_PACKAGE_RES_URL" \
        --arg res_uri "$RECEIPT_PACKAGE_RES_URI" \
        --arg res_sha "$RECEIPT_PACKAGE_RES_SHA" \
        --arg patches "$RECEIPT_PACKAGE_PATCHES" \
        --arg reslist "$RECEIPT_PACKAGE_RESLIST" \
        --arg dep_pkg "$RECEIPT_PACKAGE_DEP_PKG" \
        --arg dep_lib "$RECEIPT_PACKAGE_DEP_LIB" \
        --arg dep_upp "$RECEIPT_PACKAGE_DEP_UPP" \
        --arg dep_pip "$RECEIPT_PACKAGE_DEP_PYM" \
        --arg dep_plm "$RECEIPT_PACKAGE_DEP_PLM" \
        --arg movable "$RECEIPT_PACKAGE_MOVABLE" \
        --arg ltoable "$RECEIPT_PACKAGE_LTOABLE" \
        --arg dofetch "$RECEIPT_PACKAGE_DOFETCH" \
        --arg do12345 "$RECEIPT_PACKAGE_DO12345" \
        --arg dopatch "$RECEIPT_PACKAGE_DOPATCH" \
        --arg prepare "$RECEIPT_PACKAGE_PREPARE" \
        --arg install "$RECEIPT_PACKAGE_DOBUILD" \
        --arg doextra "$RECEIPT_PACKAGE_DOEXTRA" \
        --arg dotweak "$RECEIPT_PACKAGE_DOTWEAK" \
        --arg bindenv "$RECEIPT_PACKAGE_BINDENV" \
        --arg caveats "$RECEIPT_PACKAGE_CAVEATS" \
        --arg bsystem "$RECEIPT_PACKAGE_BSYSTEM" \
        --arg binbstd "$RECEIPT_PACKAGE_BINBSTD" \
        --arg ccflags "$RECEIPT_PACKAGE_CCFLAGS" \
        --arg xxflags "$RECEIPT_PACKAGE_XXFLAGS" \
        --arg ppflags "$RECEIPT_PACKAGE_PPFLAGS" \
        --arg ldflags "$RECEIPT_PACKAGE_LDFLAGS" \
        --arg developer "$RECEIPT_PACKAGE_DEVELOPER" \
        --arg builtby "$RECEIPT_PACKAGE_BUILTBY" \
        --arg builtat "$RECEIPT_PACKAGE_BUILTAT" \
        --arg builtfor "$RECEIPT_PACKAGE_BUILTFOR" \
'{
    "pkgname":$pkgname,
    "pkgtype":$pkgtype,
    "version":$version,
    "license":$license,
    "summary":$summary,
    "web-url":$web_url,
    "git-url":$git_url,
    "git-sha":$git_sha,
    "git-ref":$git_ref,
    "git-nth":$git_nth,
    "src-url":$src_url,
    "src-uri":$src_uri,
    "src-sha":$src_sha,
    "fix-url":$fix_url,
    "fix-uri":$fix_uri,
    "fix-sha":$fix_sha,
    "res-url":$res_url,
    "res-uri":$res_uri,
    "res-sha":$res_sha,
    "patches":$patches,
    "reslist":$reslist,
    "dep-pkg":$dep_pkg,
    "dep-lib":$dep_lib,
    "dep-upp":$dep_upp,
    "dep-pip":$dep_pip,
    "dep-plm":$dep_plm,
    "bsystem":$bsystem,
    "binbstd":$binbstd,
    "ccflags":$ccflags,
    "xxflags":$xxflags,
    "ppflags":$ppflags,
    "ldflags":$ldflags,
    "developer":$developer,
    "movable":$movable,
    "ltoable":$ltoable,
    "dofetch":$dofetch,
    "do12345":$do12345,
    "dopatch":$dopatch,
    "prepare":$prepare,
    "install":$install,
    "doextra":$doextra,
    "dotweak":$dotweak,
    "bindenv":$bindenv,
    "caveats":$caveats,
    "builtby":$builtby,
    "builtat":$builtat,
    "builtfor":$builtfor
}' | jq 'with_entries(select(.value != ""))'
}

# }}}
##############################################################################
# {{{ xcpkg depends

# __show_packages_depended_by_the_given_package <PACKAGE-NAME> [-t <d2|dot|box|svg|png>] [-e <ENGINE>] [-o <OUTPUT-PATH>]
__show_packages_depended_by_the_given_package() {
    [ -z "$1" ] && abort 1 "$XCPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], <PACKAGE-NAME> is unspecified."

    PACKAGE_NAME="$1"

    shift

    ###########################################################################################

    unset OUTPUT_TYPE
    unset OUTPUT_PATH

    unset ENGINE

    while [ -n "$1" ]
    do
        case $1 in
            -t) shift
                case $1 in
                    d2|dot|box|svg|png)
                        OUTPUT_TYPE="$1" ;;
                    '') abort 1 "$XCPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], -t option is given but <OUTPUT-TYPE> is unspecified." ;;
                    *)  abort 1 "$XCPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>], unsupported <OUTPUT-TYPE>: $1, <OUTPUT-TYPE> should be one of d2|dot|box|svg|png"
                esac
                ;;
            -e) shift
                case $1 in
                    d2|dot)
                        ENGINE="$1" ;;
                    '') abort 1 "$XCPKG_ARG0 depends <PACKAGE-NAME> [-e <ENGINE>], -e option is given but <ENGINE> is unspecified." ;;
                    *)  abort 1 "$XCPKG_ARG0 depends <PACKAGE-NAME> [-e <ENGINE>], unsupported <ENGINE>: $1, <ENGINE> should be one of d2|dot"
                esac
                ;;
            -o) shift
                if [ -z "$1" ] ; then
                    abort 1 "$XCPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], -o option is given but <OUTPUT-PATH> is unspecified."
                else
                    OUTPUT_PATH="$1"
                fi
                ;;
            *)  abort 1 "$XCPKG_ARG0 depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-o <OUTPUT-PATH>], unrecognized option: $1"
        esac
        shift
    done

    ###########################################################################################

    unset OUTPUT_DIR
    unset OUTPUT_FILEPATH

    case $OUTPUT_PATH in
        '')
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi
            ;;
        ..|../)
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi

            OUTPUT_FILEPATH="$PWD/../$PACKAGE_NAME-dependencies.$OUTPUT_TYPE"
            ;;
        .|./)
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi

            OUTPUT_FILEPATH="$PWD/$PACKAGE_NAME-dependencies.$OUTPUT_TYPE"
            ;;
        */)
            if [ -z "$OUTPUT_TYPE" ] ; then
                OUTPUT_TYPE='box'
            fi

            case $OUTPUT_PATH in
                /*) OUTPUT_DIR="$OUTPUT_PATH" ;;
                *)  OUTPUT_DIR="$PWD/$OUTPUT_PATH"
            esac

            OUTPUT_FILEPATH="$OUTPUT_DIR/$PACKAGE_NAME-dependencies.$OUTPUT_TYPE"
            ;;
        *)
            if [ -z "$OUTPUT_TYPE" ] ; then
                case $OUTPUT_PATH in
                    *.box) OUTPUT_TYPE='box' ;;
                    *.dot) OUTPUT_TYPE='dot' ;;
                    *.d2)  OUTPUT_TYPE='d2'  ;;
                    *.svg) OUTPUT_TYPE='svg' ;;
                    *.png) OUTPUT_TYPE='png' ;;
                    *)     OUTPUT_TYPE='box' ;;
                esac
            fi

            case $OUTPUT_PATH in
                /*) OUTPUT_DIR="${OUTPUT_PATH%/*}"
                    OUTPUT_FILEPATH="$OUTPUT_PATH"
                    ;;
                *)  OUTPUT_DIR="$PWD/$(dirname "$OUTPUT_PATH")"
                    OUTPUT_FILEPATH="$PWD/$OUTPUT_PATH"
            esac
    esac

    ###########################################################################################

    if [ -z "$ENGINE" ] ; then
        if [ "$OUTPUT_TYPE" = svg ] || [ "$OUTPUT_TYPE" = png ] ; then
            if command -v dot > /dev/null ; then
                ENGIN=dot
            elif command -v dot_static > /dev/null ; then
                ENGIN=dot_static
            elif command -v d2 > /dev/null ; then
                ENGIN=d2
            else
                abort 1 'none of dot, dot_static, d2 commands was found. please install graphviz or d2 package, then try again.'
            fi
        fi
    fi

    ###########################################################################################

    unset LINES

    unset DIRECTED_PATH_LIST

    STACK="$PACKAGE_NAME"

    while [ -n "$STACK" ]
    do
        case $STACK in
            *\;*) PACKAGE_NAME="${STACK##*;}" ; STACK="${STACK%;*}" ;;
            *)    PACKAGE_NAME="${STACK}"     ; STACK=
        esac

        ################################################################

        __load_formula_of_the_given_package "$PACKAGE_NAME"

        ################################################################

        [ -z "$PACKAGE_DEP_PKG" ] && continue

        ################################################################

        if [ "$OUTPUT_TYPE" = d2 ] || [ "$ENGIN" = d2 ] ; then
            for item in $PACKAGE_DEP_PKG
            do
                LINES="$LINES
$PACKAGE_NAME -> $item"
            done
        else
            unset X; X="$(printf '"%s" ' $PACKAGE_DEP_PKG)"
            unset Y; Y="$(printf '    "%s" -> { %s}\n' "$PACKAGE_NAME" "$X")"

            if [ -z "$LINES" ] ; then
                LINES="$Y"
            else
                LINES="$(printf '%s\n%s\n' "$LINES" "$Y")"
            fi
        fi

        ################################################################

        DIRECTED_PATH_LIST_PART1=
        DIRECTED_PATH_LIST_PART2=

        for DIRECTED_PATH in $DIRECTED_PATH_LIST
        do
            case $DIRECTED_PATH in
                *\>"$PACKAGE_NAME")
                    DIRECTED_PATH_LIST_PART1="$DIRECTED_PATH_LIST_PART1 $DIRECTED_PATH" ;;
                *)  DIRECTED_PATH_LIST_PART2="$DIRECTED_PATH_LIST_PART2 $DIRECTED_PATH" ;;
            esac
        done

        ################################################################

        # it will be recalculated
        DIRECTED_PATH_LIST=

        ################################################################

        for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
        do
            if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                abort 1 "package [$PACKAGE_NAME] depends itself."
            fi

            ############################################################

            if [ -z "$DIRECTED_PATH_LIST_PART1" ] ; then
                DIRECTED_PATH_LIST="$DIRECTED_PATH_LIST $PACKAGE_NAME>$DEPENDENT_PACKAGE_NAME"
            else
                for DIRECTED_PATH in $DIRECTED_PATH_LIST_PART1
                do
                    export IFS='>'

                    # check if have duplicate nodes in every directed path
                    for node in $DIRECTED_PATH
                    do
                        if [ "$node" = "$DEPENDENT_PACKAGE_NAME" ] ; then
                            abort 1 "depends has circle: $DIRECTED_PATH>$DEPENDENT_PACKAGE_NAME"
                        fi
                    done

                    unset IFS

                    DIRECTED_PATH_LIST="$DIRECTED_PATH_LIST $DIRECTED_PATH>$DEPENDENT_PACKAGE_NAME"
                done
            fi

            ############################################################

            if [ -z "$STACK" ] ; then
                STACK="$DEPENDENT_PACKAGE_NAME"
            else
                STACK="$STACK;$DEPENDENT_PACKAGE_NAME"
            fi
        done

        DIRECTED_PATH_LIST="$DIRECTED_PATH_LIST $DIRECTED_PATH_LIST_PART2"
    done

    ###########################################################################################

    [ -z "$LINES" ] && return 0

    ###########################################################################################

    case $OUTPUT_TYPE in
        dot)
            if [ -z "$OUTPUT_FILEPATH" ] ; then
                printf 'digraph G {\n%s\n}\n' "$LINES"
            else
                SESSION_DIR="$XCPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                printf 'digraph G {\n%s\n}\n' "$LINES" > dependencies.dot

                if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                    install -d "$OUTPUT_DIR"
                fi

                mv -T dependencies.dot "$OUTPUT_FILEPATH"

                rm -rf "$SESSION_DIR"
            fi
            ;;
        d2)
            if [ -z "$OUTPUT_FILEPATH" ] ; then
                printf '%s\n' "$LINES"
            else
                SESSION_DIR="$XCPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                printf '%s\n' "$LINES" > dependencies.d2

                if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                    install -d "$OUTPUT_DIR"
                fi

                mv -T dependencies.d2 "$OUTPUT_FILEPATH"

                rm -rf "$SESSION_DIR"
            fi
            ;;
        box)
            DOT_CONTENT="digraph G {
$LINES
}"

            if [ -z "$OUTPUT_FILEPATH" ] ; then
                # https://github.com/ggerganov/dot-to-ascii
                curl \
                    -s \
                    -G \
                    --data-urlencode "boxart=1" \
                    --data-urlencode "src=$DOT_CONTENT" \
                    'https://dot-to-ascii.ggerganov.com/dot-to-ascii.php'
            else
                SESSION_DIR="$XCPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                # https://github.com/ggerganov/dot-to-ascii
                curl \
                    -s \
                    -G \
                    -o dependencies.box \
                    --data-urlencode "boxart=1" \
                    --data-urlencode "src=$DOT_CONTENT" \
                    'https://dot-to-ascii.ggerganov.com/dot-to-ascii.php'

                if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                    install -d "$OUTPUT_DIR"
                fi

                mv dependencies.box "$OUTPUT_FILEPATH"

                rm -rf "$SESSION_DIR"
            fi
            ;;
        svg|png)
            if [ "$ENGIN" = d2 ] ; then
                if [ -z "$OUTPUT_FILEPATH" ] ; then
                    printf '%s\n' "$LINES" | d2 -
                else
                    if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                        install -d "$OUTPUT_DIR"
                    fi

                    printf '%s\n' "$LINES" | d2 - "$OUTPUT_FILEPATH"
                fi
            else
                SESSION_DIR="$XCPKG_HOME/run/$$"

                rm -rf     "$SESSION_DIR"
                install -d "$SESSION_DIR"
                cd         "$SESSION_DIR"

                printf 'digraph G {\n%s\n}\n' "$LINES" > dependencies.dot

                if [ -z "$OUTPUT_FILEPATH" ] ; then
                    "$ENGIN" "-T$OUTPUT_TYPE" dependencies.dot
                else
                    "$ENGIN" "-T$OUTPUT_TYPE" -o dependencies.tmp dependencies.dot

                    if [ -n "$OUTPUT_DIR" ] && [ ! -d "$OUTPUT_DIR" ] ; then
                        install -d "$OUTPUT_DIR"
                    fi

                    mv -T dependencies.tmp "$OUTPUT_FILEPATH"
                fi

                rm -rf "$SESSION_DIR"
            fi
    esac
}

# }}}
##############################################################################
# {{{ xcpkg fetch

__fetch_resources_of_the_given_package() {
    if [ -z "$1" ] ; then
        abort 1 "__fetch_resources_of_the_given_package <PACKAGE-NAME>, <PACKAGE-NAME> is unspecified."
    fi

    __load_formula_of_the_given_package "$1"

    if [ -n "$PACKAGE_SRC_URL" ] ; then
        case $PACKAGE_SRC_URL in
            dir://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                return 0
                ;;
            file://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                return 0
                ;;
            *)  wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH"
        esac
    elif [ -n "$PACKAGE_GIT_URL" ] ; then
        unset GIT_FETCH_URL

        if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
            GIT_FETCH_URL="$PACKAGE_GIT_URL"
        else
            GIT_FETCH_URL="$("$XCPKG_URL_TRANSFORM" "$PACKAGE_GIT_URL")" || return 1
        fi

        if [ -z "$PACKAGE_GIT_SHA" ] ; then
            if [ -z "$PACKAGE_GIT_REF" ] ; then
                GIT_BRANCH_NAME=master
                GIT_REF_SPEC="+HEAD:refs/remotes/origin/master"
            else
                GIT_BRANCH_NAME="${PACKAGE_GIT_REF##*/}"
                GIT_REF_SPEC="+$PACKAGE_GIT_REF:refs/remotes/origin/$GIT_BRANCH_NAME"
            fi
        else
            GIT_BRANCH_NAME=master
            GIT_REF_SPEC="+$PACKAGE_GIT_SHA:refs/remotes/origin/master"
        fi

        if [ -z "$PACKAGE_GIT_NTH" ] ; then
            PACKAGE_GIT_NTH=1
        fi

        if [ "$PACKAGE_GIT_NTH" -eq 0 ] ; then
            if [ -f "$PACKAGE_SRC_FILEPATH/.git/shallow" ] ; then
                GIT_FETCH_EXTRA_OPTIONS='--unshallow'
            else
                GIT_FETCH_EXTRA_OPTIONS=
            fi
        else
            GIT_FETCH_EXTRA_OPTIONS="--depth=$PACKAGE_GIT_NTH"
        fi

        SESSION_DIR="$XCPKG_HOME/run/$$"

        run rm -rf     "$SESSION_DIR"
        run install -d "$SESSION_DIR"
        run cd         "$SESSION_DIR"
        run git -c init.defaultBranch=master init
        run git remote add origin "$GIT_FETCH_URL"
        run git -c protocol.version=2 fetch --progress $GIT_FETCH_EXTRA_OPTIONS origin "$GIT_REF_SPEC"
        run git checkout --progress --force -B "$GIT_BRANCH_NAME" "refs/remotes/origin/$GIT_BRANCH_NAME"

        git_submodule_update_recursive

        rm -rf "$SESSION_DIR"
    fi

    if [ -n    "$PACKAGE_FIX_URL" ] ; then
        wfetch "$PACKAGE_FIX_URL" --uri="$PACKAGE_FIX_URI" --sha256="$PACKAGE_FIX_SHA" -o "$PACKAGE_FIX_FILEPATH"
    fi

    if [ -n    "$PACKAGE_RES_URL" ] ; then
        wfetch "$PACKAGE_RES_URL" --uri="$PACKAGE_RES_URI" --sha256="$PACKAGE_RES_SHA" -o "$PACKAGE_RES_FILEPATH"
    fi
}

# }}}
##############################################################################
# {{{ xcpkg tree

# __tree_the_given_installed_package <PACKAGE-SPEC>
  __tree_the_given_installed_package() {
    PACKAGE_SPEC=
    PACKAGE_SPEC="$(inspect_package_spec "$1")"

    if is_package_installed "$PACKAGE_SPEC" ; then
        PACKAGE_INSTALLED_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
    else
        abort 1 "package '$PACKAGE_SPEC' is not installed."
    fi

    shift

    run tree "$@" "$PACKAGE_INSTALLED_DIR"
}

# }}}
##############################################################################
# {{{ xcpkg logs

# __logs_the_given_installed_package <PACKAGE-SPEC>
  __logs_the_given_installed_package() {
    PACKAGE_SPEC="$(inspect_package_spec "$1")"

    if is_package_installed "$PACKAGE_SPEC" ; then
        PACKAGE_INSTALLED_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
    else
        abort 1 "package '$PACKAGE_SPEC' is not installed."
    fi

    cd "$PACKAGE_INSTALLED_DIR/.xcpkg"

    fzf --preview='bat --color=always --theme=Dracula {}' --preview-window='right:75%'
}

# }}}
##############################################################################
# {{{ xcpkg bundle

# __bundle_the_given_installed_package <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>] [--exclude <EXCLUDE-PATH>] [-K]
  __bundle_the_given_installed_package() {
    __load_receipt_of_the_given_package "$1"

    #######################################################

    unset OUTPUT_DIR
    unset OUTPUT_PATH
    unset OUTPUT_TYPE
    unset OUTPUT_NAME

    case $2 in
        '') abort 1 "$XCPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>], forth argument is unspecified."
            ;;
        */*)
            OUTPUT_DIR="${2%/*}"
            [ -z "$OUTPUT_DIR" ] && OUTPUT_DIR=/
            OUTPUT_NAME="${2##*/}"
            ;;
        *)  OUTPUT_NAME="$2"
    esac

    case $OUTPUT_NAME in
        '') abort 1 "$XCPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>, <BUNDLE-TYPE> is unspecified."
            ;;
        *.tar.gz)
            OUTPUT_TYPE=.tar.gz
            ;;
        *.tar.xz)
            OUTPUT_TYPE=.tar.xz
            ;;
        *.tar.lz)
            OUTPUT_TYPE=.tar.lz
            ;;
        *.tar.bz2)
            OUTPUT_TYPE=.tar.bz2
            ;;
        *.zip)
            OUTPUT_TYPE=.zip
            ;;
        *)  abort 1 "$XCPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>, invalid forth argument: $2"
    esac

    if [ "$OUTPUT_NAME" = "$OUTPUT_TYPE" ] ; then
        if [ -z "$OUTPUT_DIR"  ] ; then
            OUTPUT_PATH=.
        else
            OUTPUT_PATH="$OUTPUT_DIR/"
        fi
    else
        OUTPUT_PATH="$2"
    fi

    #######################################################

    shift 2

    unset KEEP_SESSION_DIR

    unset EXCLUDES

    while [ -n "$1" ]
    do
        case $1 in
            -K)
                KEEP_SESSION_DIR=1
                ;;
            --exclude)
                shift
                if [ -z "$1" ] ; then
                    abort 1 "$XCPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>] [--exclude <PATH>], --exclude option is specified but <PATH> is unspecified."
                else
                    EXCLUDES="$EXCLUDES $1"
                fi
                ;;
            *)  abort 1 "$XCPKG_ARG0 bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE>] [--portable], unrecognized option: $1"
        esac
        shift
    done

    #######################################################

    OLDCWD="$PWD"

    SESSION_DIR="$XCPKG_HOME/run/$$"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    #######################################################

    if [ -n "$EXCLUDES" ] ; then
        run install -d bundle.d/

        run cp -r "$PACKAGE_INSTALLED_DIR/." bundle.d/

        for EXCLUDE in $EXCLUDES
        do
            run rm -rf "bundle.d/$EXCLUDE"
        done
    else
        run ln -s "$PACKAGE_INSTALLED_DIR" bundle.d
    fi

    ###########################################################################################

    BUNDLE_DIR_NAME="${RECEIPT_PACKAGE_PKGNAME%@*}-$RECEIPT_PACKAGE_VERSION-$RECEIPT_PACKAGE_BUILTFOR_PLATFORM"

    BUNDLE_DIR_NAME="$BUNDLE_DIR_NAME.$RECEIPT_PACKAGE_PROFILE"

    OUTPUT_FILENAME="$BUNDLE_DIR_NAME$OUTPUT_TYPE"

    #######################################################

    run mv bundle.d "$BUNDLE_DIR_NAME"

    run bsdtar cvaf "$OUTPUT_FILENAME" "$BUNDLE_DIR_NAME/*" "$BUNDLE_DIR_NAME/.xcpkg"

    run du -sh "$OUTPUT_FILENAME"

    run cd "$OLDCWD"

    if [ -n "$OUTPUT_DIR" ] && [ "$OUTPUT_DIR" != . ] && [ "$OUTPUT_DIR" != .. ] && [ "$OUTPUT_DIR" != / ] && [ ! -d "$OUTPUT_DIR" ] ; then
        run install -d "$OUTPUT_DIR"
    fi

    run mv "$SESSION_DIR/$OUTPUT_FILENAME" "$OUTPUT_PATH"

    #######################################################

    if [ "$KEEP_SESSION_DIR" = 1 ] ; then
        echo
        note "the session directory '$SESSION_DIR' is not deleted as -K option is specified."
    else
        run rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ xcpkg xcinfo

__inspect_xcode_info() {
    if [ -z "$1" ] ; then
        if [ -z "$DEVELOPER_DIR" ] ; then
            export DEVELOPER_DIR="$(xcode-select -p)"
            [ -z "$DEVELOPER_DIR" ] && abort 1 "Xcode developer dir can't be located.\nThere're 3 ways to resolve this problem:\n1. run command 'xcode-select --switch DEVELOPER_DIR', then try again.\n2. set system-wide environment variable DEVELOPER_DIR\3. set process-wide environment variable DEVELOPER_DIR, you can run xcpkg command as 'DEVELOPER_DIR=/some/path xcpkg'"
        else
            note "you have set DEVELOPER_DIR=$DEVELOPER_DIR, it will be used as the xcode developer directory."
        fi
    else
        export DEVELOPER_DIR="$1"
    fi

    [ -e "$DEVELOPER_DIR" ] || abort 1 "$DEVELOPER_DIR directory was expected to be exist, but it was not."
    [ -d "$DEVELOPER_DIR" ] || abort 1 "$DEVELOPER_DIR was expected to be a directory, but it was not."

    XCODE_ROOT="${DEVELOPER_DIR%/*}"

    XCODE_VERSION_PLIST_FILEPATH="$XCODE_ROOT/version.plist"

    [ -e "$XCODE_VERSION_PLIST_FILEPATH" ] || abort 1 "$XCODE_VERSION_PLIST_FILEPATH file was expected to be exist, but it was not."
    [ -f "$XCODE_VERSION_PLIST_FILEPATH" ] || abort 1 "$XCODE_VERSION_PLIST_FILEPATH was expected to be a regular file, but it was not."

    XCODE_VERSION=
    XCODE_VERSION="$(/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' "$XCODE_VERSION_PLIST_FILEPATH")"

    XCODE_TOOLCHAIN_BIN_DIR="$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/bin"

    [ -e "$XCODE_TOOLCHAIN_BIN_DIR" ] || abort 1 "$XCODE_TOOLCHAIN_BIN_DIR was expected to be exist, but it was not."
    [ -d "$XCODE_TOOLCHAIN_BIN_DIR" ] || abort 1 "$XCODE_TOOLCHAIN_BIN_DIR was expected to be a directory, but it was not."

    XCODE_CC="$XCODE_TOOLCHAIN_BIN_DIR/clang"
    XCODE_CXX="$XCODE_TOOLCHAIN_BIN_DIR/clang++"
    XCODE_CPP="$XCODE_TOOLCHAIN_BIN_DIR/cpp"
    XCODE_AS="$XCODE_TOOLCHAIN_BIN_DIR/as"
    XCODE_AR="$XCODE_TOOLCHAIN_BIN_DIR/ar"
    XCODE_RANLIB="$XCODE_TOOLCHAIN_BIN_DIR/ranlib"
    XCODE_LD="$XCODE_TOOLCHAIN_BIN_DIR/ld"
    XCODE_NM="$XCODE_TOOLCHAIN_BIN_DIR/nm"
    XCODE_SIZE="$XCODE_TOOLCHAIN_BIN_DIR/size"
    XCODE_STRIP="$XCODE_TOOLCHAIN_BIN_DIR/strip"
    XCODE_STRINGS="$XCODE_TOOLCHAIN_BIN_DIR/strings"
    XCODE_OBJDUMP="$XCODE_TOOLCHAIN_BIN_DIR/objdump"

    XCODE_PLATFORM_NAMES=

    XCODE_PLATFORMS_DIR="$DEVELOPER_DIR/Platforms"

    if [ -d "$XCODE_PLATFORMS_DIR" ] ; then
        for item in $(cd "$XCODE_PLATFORMS_DIR" && ls)
        do
            case $item in
                *.platform)
                    if [ -z "$XCODE_PLATFORM_NAMES" ] ; then
                        XCODE_PLATFORM_NAMES="${item%.platform}"
                    else
                        XCODE_PLATFORM_NAMES="$XCODE_PLATFORM_NAMES ${item%.platform}"
                    fi
            esac
        done

        if [ -z "$XCODE_PLATFORM_NAMES" ] ; then
            abort 1 "no any platforms found in $XCODE_PLATFORMS_DIR"
        fi
    else
        [ -e "$XCODE_PLATFORMS_DIR" ] || abort 1 "$XCODE_PLATFORMS_DIR was expected to be exist, but it was not."
        [ -d "$XCODE_PLATFORMS_DIR" ] || abort 1 "$XCODE_PLATFORMS_DIR was expected to be a directory, but it was not."
    fi

    for TARGET_PLATFORM_NAME in $XCODE_PLATFORM_NAMES
    do
        SDKNAME="$(printf '%s\n' "$TARGET_PLATFORM_NAME" | tr A-Z a-z)"
        SDKROOT="$(xcrun --sdk "$SDKNAME" --show-sdk-path)"
        SDKSettingsFILEPATH="$SDKROOT/SDKSettings.json"
        SDK_SUPPORTED_ARCHS="$(jq -r ".SupportedTargets.$SDKNAME.Archs | join(\" \")" "$SDKSettingsFILEPATH")"
        SDK_SUPPORTED_VERSIONS="$(jq -r ".SupportedTargets.$SDKNAME.ValidDeploymentTargets | reverse | join(\" \")" "$SDKSettingsFILEPATH")"

        eval "XCODE_${TARGET_PLATFORM_NAME}_SDKROOT='$SDKROOT'"
        eval "XCODE_${TARGET_PLATFORM_NAME}_ARCHS='$SDK_SUPPORTED_ARCHS'"
        eval "XCODE_${TARGET_PLATFORM_NAME}_VERSIONS='$SDK_SUPPORTED_VERSIONS'"
    done
}

__println_xcode_info() {
    cat <<EOF
DEVELOPER_DIR='$DEVELOPER_DIR'
XCODE_VERSION='$XCODE_VERSION'
XCODE_CC='$XCODE_CC'
XCODE_CXX='$XCODE_CXX'
XCODE_CPP='$XCODE_CPP'
XCODE_AS='$XCODE_AS'
XCODE_AR='$XCODE_AR'
XCODE_RANLIB='$XCODE_RANLIB'
XCODE_LD='$XCODE_LD'
XCODE_NM='$XCODE_NM'
XCODE_SIZE='$XCODE_SIZE'
XCODE_STRIP='$XCODE_STRIP'
XCODE_STRINGS='$XCODE_STRINGS'
XCODE_OBJDUMP='$XCODE_OBJDUMP'

XCODE_PLATFORM_NAMES='$XCODE_PLATFORM_NAMES'
EOF

    for TARGET_PLATFORM_NAME in $XCODE_PLATFORM_NAMES
    do
        eval "SDKROOT=\"\$XCODE_${TARGET_PLATFORM_NAME}_SDKROOT\""
        eval "SDK_SUPPORTED_ARCHS=\"\$XCODE_${TARGET_PLATFORM_NAME}_ARCHS\""
        eval "SDK_SUPPORTED_VERSIONS=\"\$XCODE_${TARGET_PLATFORM_NAME}_VERSIONS\""

        cat <<EOF

XCODE_${TARGET_PLATFORM_NAME}_SDKROOT='$SDKROOT'
XCODE_${TARGET_PLATFORM_NAME}_ARCHS='$SDK_SUPPORTED_ARCHS'
XCODE_${TARGET_PLATFORM_NAME}_VERSIONS='$SDK_SUPPORTED_VERSIONS'
EOF
    done
}

# https://www.gnu.org/software/gettext/manual/html_node/config_002eguess.html
# https://git.savannah.gnu.org/cgit/config.git/tree/
  __update_config_sub_guess() {
    run cd "$SESSION_DIR"

    if [ -f config/config.sub ] && [ -f config/config.guess ] ; then
        CONFIG_FILE_DIR="$SESSION_DIR/config"
    else
        if [    -d config.git ] ; then
            rm -rf config.git
        fi

        if run git clone --depth 1 https://git.savannah.gnu.org/git/config.git ; then
            CONFIG_FILE_DIR="$SESSION_DIR/config"

            if [ "$TARGET_PLATFORM_ARCH" = arm64e ] ; then
                gsed -i 's/arm64-*/arm64-*|arm64e-*/g' config/config.sub
            fi
        else
            if  run curl -L -o _config.sub   "'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'" &&
                sh _config.sub x86_64-pc-linux &&
                run curl -L -o _config.guess "'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'" &&
                sh _config.guess > /dev/null ; then
                run chmod +x _config.guess
                run chmod +x _config.sub
                run mv _config.guess config.guess
                run mv _config.sub   config.sub
                CONFIG_FILE_DIR="$SESSION_DIR"
            elif run curl -L -o _config.sub   'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub' &&
                sh _config.sub x86_64-pc-linux &&
                run curl -L -o _config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess' &&
                sh _config.guess > /dev/null ; then

                if [ "$TARGET_PLATFORM_ARCH" = arm64e ] ; then
                    gsed -i 's/arm64-*/arm64-*|arm64e-*/g' _config.sub
                fi

                run chmod +x _config.guess
                run chmod +x _config.sub
                run mv _config.guess config.guess
                run mv _config.sub   config.sub
                CONFIG_FILE_DIR="$SESSION_DIR"
            else
                CONFIG_FILE_DIR="$NDKPKG_CORE_DIR"
            fi
        fi
    fi

    run cd -

    find -type f -name config.sub   -exec cp -vf "$CONFIG_FILE_DIR/config.sub"   {} \;
    find -type f -name config.guess -exec cp -vf "$CONFIG_FILE_DIR/config.guess" {} \;
}

# should run in subshell
install_the_given_native_package() {
    [ -z "$1" ] && abort 1 "install_the_given_native_package <PACKAGE-NAME> , <PACKAGE-NAME> is unspecified."

    unset PACKAGE_SRC_URL
    unset PACKAGE_SRC_URI
    unset PACKAGE_SRC_SHA

    unset PACKAGE_DEP_PKG
    unset PACKAGE_DEP_AUX
    unset PACKAGE_DEP_RUN

    unset PACKAGE_DOPATCH
    unset PACKAGE_INSTALL
    unset PACKAGE_DOTWEAK

    if [ "$1" = 'perl-XML-Parser' ] ; then
        native_package_info_perl_XML_Parser
    else
        native_package_info_$1
    fi

    #########################################################################################

    for PACKAGE_DEPENDENCY in $PACKAGE_DEP_PKG
    do
        (install_the_given_native_package "$PACKAGE_DEPENDENCY")
    done

    #########################################################################################

    printf '\n%b\n' "${COLOR_PURPLE}=>> install native package : $1${COLOR_OFF}"

    if [ -f "$NATIVE_PACKAGE_INSTALLED_ROOT/$1/receipt.txt" ] ; then
        note "native package '$1' already has been installed, skipped."
        return 0
    fi

    #########################################################################################

    for UPPM_PACKAGE_NAME in $PACKAGE_DEP_AUX
    do
        run "$UPPM" install "$UPPM_PACKAGE_NAME" "$UPPM_INSTALL_ARGS"

        UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME"

        if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then
            PATH="$UPPM_PACKAGE_INSTALLED_DIR/bin:$PATH"
        fi

        if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            PATH="$UPPM_PACKAGE_INSTALLED_DIR/sbin:$PATH"
        fi
    done

    #########################################################################################

    PACKAGE_INSTALL_UTS=
    PACKAGE_INSTALL_UTS="$(date +%s)"

    PACKAGE_INSTALL_SHA=
    PACKAGE_INSTALL_SHA="$(
{
    sha256sum <<EOF
$1:$PACKAGE_SRC_URL:$$:$PACKAGE_INSTALL_UTS
EOF
} | cut -d ' ' -f1)"

    #########################################################################################

    PACKAGE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_INSTALL_SHA"

    PACKAGE_SRC_FILETYPE="$(filetype_from_url "$PACKAGE_SRC_URL")"
    PACKAGE_SRC_FILENAME="$PACKAGE_SRC_SHA$PACKAGE_SRC_FILETYPE"
    PACKAGE_SRC_FILEPATH="$XCPKG_DOWNLOADS_DIR/$PACKAGE_SRC_FILENAME"

    PACKAGE_WORKING_DIR="$SESSION_DIR/native/$1"

    #########################################################################################

    # override the default search directory (usually /usr/lib/pkgconfig:/usr/share/pkgconfig)
    # because we only want to use our own
    export PKG_CONFIG_LIBDIR="$PACKAGE_WORKING_DIR/lib/pkgconfig"
    export PKG_CONFIG_PATH="$PACKAGE_WORKING_DIR/lib/pkgconfig:$PKG_CONFIG_PATH"
    export ACLOCAL_PATH="$PACKAGE_WORKING_DIR/share/aclocal"
    export CPPFLAGS="-I$PACKAGE_WORKING_DIR/include $CPPFLAGS"
    export LDFLAGS="-L$PACKAGE_WORKING_DIR/lib -Wl,-rpath,$PACKAGE_INSTALL_DIR/lib $LDFLAGS"

    for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
    do
        DEPENDENT_PACKAGE_INSTALLED_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME"

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/include" ] ; then
            CPPFLAGS="-I$DEPENDENT_PACKAGE_INSTALLED_DIR/include $CPPFLAGS"
        fi

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/lib" ] ; then
            LDFLAGS="-L$DEPENDENT_PACKAGE_INSTALLED_DIR/lib -Wl,-rpath,$DEPENDENT_PACKAGE_INSTALLED_DIR/lib $LDFLAGS"
        fi

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/bin" ] ; then
            PATH="$DEPENDENT_PACKAGE_INSTALLED_DIR/bin:$PATH"
        fi

        if [ -d  "$DEPENDENT_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            PATH="$DEPENDENT_PACKAGE_INSTALLED_DIR/sbin:$PATH"
        fi

        if [ -d          "$DEPENDENT_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
            ACLOCAL_PATH="$DEPENDENT_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH"
        fi

        for d in lib share
        do
            DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALLED_DIR/$d/pkgconfig"

            if [ -d "$DEPENDENT_PACKAGE_PKGCONF_DIR" ] ; then
                PKG_CONFIG_PATH="$DEPENDENT_PACKAGE_PKGCONF_DIR:$PKG_CONFIG_PATH"
            fi
        done
    done

    #########################################################################################

    wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH"

    #########################################################################################

    run install -d "$PACKAGE_WORKING_DIR/src"
    run cd         "$PACKAGE_WORKING_DIR/src"

    #########################################################################################

    run bsdtar xf "$PACKAGE_SRC_FILEPATH" --strip-components=1 --no-same-owner

    #########################################################################################

    if [ -n  "$PACKAGE_DOPATCH" ] ; then
        eval "$PACKAGE_DOPATCH"
    fi

    #########################################################################################

    if [ -z "$PACKAGE_INSTALL" ] ; then
        abort 1 "PACKAGE_INSTALL variable is not set for native package '$1'"
    fi

    case "${PACKAGE_INSTALL%% *}" in
        configure)
            __update_config_sub_guess
            PACKAGE_INSTALL="run ./$PACKAGE_INSTALL --prefix=$PACKAGE_INSTALL_DIR && run gmake --jobs=$BUILD_NJOBS && run gmake install"
            ;;
        config)
            PACKAGE_INSTALL="run ./$PACKAGE_INSTALL --prefix=$PACKAGE_INSTALL_DIR && run gmake --jobs=$BUILD_NJOBS && run gmake install_sw"
            ;;
        perl)
            PACKAGE_INSTALL="run   $PACKAGE_INSTALL --prefix=$PACKAGE_INSTALL_DIR && run gmake --jobs=$BUILD_NJOBS && run gmake install && run install -d $PACKAGE_INSTALL_DIR"
            ;;
        cmake)
            PACKAGE_INSTALL="run $PACKAGE_INSTALL -DCMAKE_INSTALL_PREFIX=$PACKAGE_INSTALL_DIR -DENABLE_TESTING=OFF -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=Release -G Ninja -S . -B build.d && run cmake --build build.d -- -j$BUILD_NJOBS && run cmake --install build.d"
            ;;
    esac

    eval "$PACKAGE_INSTALL"

    #########################################################################################

    run cd "$PACKAGE_INSTALL_DIR"

    #########################################################################################

    if [ -n  "$PACKAGE_DOTWEAK" ] ; then
        eval "$PACKAGE_DOTWEAK"
    fi

    #########################################################################################

    run cd "$PACKAGE_INSTALL_DIR"

    #########################################################################################

    cat > buildon.yml <<EOF
os-arch: $NATIVE_PLATFORM_ARCH
os-kind: $NATIVE_PLATFORM_KIND
os-type: $NATIVE_PLATFORM_TYPE
os-libc: $NATIVE_PLATFORM_LIBC
os-code: $NATIVE_PLATFORM_CODE
os-name: $NATIVE_PLATFORM_NAME
os-vers: $NATIVE_PLATFORM_VERS
os-ncpu: $NATIVE_PLATFORM_NCPU
os-euid: $NATIVE_PLATFORM_EUID
os-egid: $NATIVE_PLATFORM_EGID
EOF

    #########################################################################################

    cat > toolchain.txt <<EOF
     CC='$CC'
    CXX='$CXX'
     AS='$AS'
     LD='$LD'
     AR='$AR'
 RANLIB='$RANLIB'
SYSROOT='$SYSROOT'
EOF

    #########################################################################################

    cat > receipt.txt <<EOF
PACKAGE_SRC_URL='$PACKAGE_SRC_URL'
PACKAGE_SRC_URI='$PACKAGE_SRC_URI'
PACKAGE_SRC_SHA='$PACKAGE_SRC_SHA'

PACKAGE_DEP_PKG='$PACKAGE_DEP_PKG'
PACKAGE_DEP_AUX='$PACKAGE_DEP_AUX'
PACKAGE_DEP_RUN='$PACKAGE_DEP_RUN'

PACKAGE_DOPATCH='$PACKAGE_DOPATCH'
PACKAGE_DOTWEAK='$PACKAGE_DOTWEAK'
PACKAGE_INSTALL='$PACKAGE_INSTALL'
PACKAGE_INSTALL_UTS='$PACKAGE_INSTALL_UTS'
EOF

    #########################################################################################

    run cd "$NATIVE_PACKAGE_INSTALLED_ROOT"
    run ln -s -f -T "$PACKAGE_INSTALL_SHA" "$1"
}

native_package_info_libz() {
    PACKAGE_SRC_URL='https://zlib.net/zlib-1.3.1.tar.gz'
    PACKAGE_SRC_SHA='9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23'
    PACKAGE_DEP_AUX='gsed cmake ninja'
    PACKAGE_DOPATCH='gsed -i "s|/share/pkgconfig|/lib/pkgconfig|" CMakeLists.txt'
    PACKAGE_INSTALL='cmake -DZLIB_BUILD_EXAMPLES=OFF -G Ninja'
}

native_package_info_libopenssl() {
    PACKAGE_SRC_URL='https://www.openssl.org/source/openssl-3.3.1.tar.gz'
    PACKAGE_SRC_SHA='777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DOPATCH='
    case $NATIVE_PLATFORM_ARCH in
        armv7l) gsed -i "s|armv7-a|armv7-a+fp|g" util/perl/OpenSSL/config.pm
    esac'
    PACKAGE_INSTALL='config no-tests no-ssl3 no-ssl3-method no-zlib --libdir=lib --openssldir=etc/ssl'
    # https://github.com/openssl/openssl/blob/master/INSTALL.md
}

native_package_info_libtool() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/libtool/libtool-2.4.7.tar.xz'
    PACKAGE_SRC_SHA='4f7f217f057ce655ff22559ad221a0fd8ef84ad1fc5fcb6990cecc333aa1635d'
    PACKAGE_INSTALL='configure --enable-ltdl-install'
    PACKAGE_DEP_AUX='gm4 gmake'
    PACKAGE_DOTWEAK='
run ln -s libtool    bin/glibtool
run ln -s libtoolize bin/glibtoolize
'
}

native_package_info_autoconf() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz'
    PACKAGE_SRC_SHA='431075ad0bf529ef13cb41e9042c542381103e80015686222b8a9d4abef42a1c'
    PACKAGE_DEP_AUX='perl gm4 gmake'
    PACKAGE_DEP_RUN='perl gm4'
    PACKAGE_INSTALL='configure'
}

native_package_info_automake() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/automake/automake-1.16.5.tar.xz'
    PACKAGE_SRC_SHA='f01d58cd6d9d77fbdca9eb4bbd5ead1988228fdb73d6f7a201f5f8d6b118b469'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DEP_PKG='autoconf'
    PACKAGE_INSTALL='configure'
}

native_package_info_texinfo() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/texinfo/texinfo-7.2.tar.xz'
    PACKAGE_SRC_SHA='0329d7788fbef113fa82cb80889ca197a344ce0df7646fe000974c5d714363a6'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DOPATCH='gsed -i "/libintl/d" tp/Texinfo/XS/parsetexi/api.c'
    PACKAGE_INSTALL='configure --with-included-regex --enable-threads=posix --disable-nls'
}

native_package_info_help2man() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/help2man/help2man-1.49.3.tar.xz'
    PACKAGE_SRC_SHA='4d7e4fdef2eca6afe07a2682151cea78781e0a4e8f9622142d9f70c083a2fd4f'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_INSTALL='configure'
}

native_package_info_libexpat() {
    PACKAGE_SRC_URL='https://github.com/libexpat/libexpat/releases/download/R_2_6_4/expat-2.6.4.tar.xz'
    PACKAGE_SRC_SHA='a695629dae047055b37d50a0ff4776d1d45d0a4c842cf4ccee158441f55ff7ee'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure --disable-dependency-tracking --enable-static --enable-shared --without-xmlwf --without-tests --without-examples --without-docbook'
}

native_package_info_intltool() {
    PACKAGE_SRC_URL='https://launchpad.net/intltool/trunk/0.51.0/+download/intltool-0.51.0.tar.gz'
    PACKAGE_SRC_URI='https://fossies.org/linux/privat/intltool-0.51.0.tar.gz'
    PACKAGE_SRC_SHA='67c74d94196b153b774ab9f89b2fa6c6ba79352407037c8c14d5aeb334e959cd'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DEP_PKG='libexpat perl-XML-Parser'
    PACKAGE_INSTALL='configure'
}

native_package_info_perl_XML_Parser() {
    PACKAGE_SRC_URL='https://cpan.metacpan.org/authors/id/T/TO/TODDR/XML-Parser-2.47.tar.gz'
    PACKAGE_SRC_SHA='ad4aae643ec784f489b956abe952432871a622d4e2b5c619e8855accbfc4d1d8'
    PACKAGE_DEP_AUX='perl gmake'
    PACKAGE_DEP_RUN='perl'
    PACKAGE_DEP_PKG='libexpat'
    PACKAGE_DOPATCH='
run export EXPATLIBPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/lib"
run export EXPATINCPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/include"
run gsed -i "\"/check_lib/a not_execute,\"" Makefile.PL
'
    if [ "$NATIVE_PLATFORM_KIND" = darwin ] ; then
        PACKAGE_INSTALL='perl Makefile.PL'
    else
        PACKAGE_INSTALL='perl Makefile.PL LDDLFLAGS="\"-shared -L$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/lib -Wl,-rpath,$NATIVE_PACKAGE_INSTALLED_ROOT/libexpat/lib\""'
    fi
}

native_package_info_libiconv() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/libiconv/libiconv-1.17.tar.gz'
    PACKAGE_SRC_SHA='8f74213b56238c85a50a5329f77e06198771e70dd9a739779f4c02f65d971313'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure --disable-dependency-tracking --enable-static --enable-shared --enable-extra-encodings'
}

native_package_info_libxml2() {
    PACKAGE_SRC_URL='https://download.gnome.org/sources/libxml2/2.12/libxml2-2.12.6.tar.xz'
    PACKAGE_SRC_SHA='889c593a881a3db5fdd96cc9318c87df34eb648edfc458272ad46fd607353fbb'
    PACKAGE_DEP_PKG='libz libiconv'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure --with-zlib --with-python --with-iconv="$NATIVE_PACKAGE_INSTALLED_ROOT/libiconv" --without-lzma --without-readline --without-coverage --without-debug --enable-ipv6 --enable-static --enable-shared LIBS=-liconv'
}

native_package_info_itstool() {
    PACKAGE_SRC_URL='https://github.com/itstool/itstool/archive/2.0.7.tar.gz'
    PACKAGE_SRC_SHA='fba78a37dc3535e4686c7f57407b97d03c676e3a57beac5fb2315162b0cc3176'
    PACKAGE_DEP_AUX='perl python3 gmake'
    PACKAGE_DEP_RUN='perl python3'
    PACKAGE_DEP_PKG='libxml2 autoconf automake'
    PACKAGE_INSTALL='configure'
    PACKAGE_DOPATCH='
    run autoreconf -ivf
    export PYTHON="$(command -v python3)"
    export PYTHONPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/libxml2/lib/python3.11/site-packages"
    '
    PACKAGE_DOTWEAK='
run mv bin/itstool bin/itstool.py
cat > bin/itstool <<EOF
#!/bin/sh
export PYTHONPATH="$PYTHONPATH"
exec "$PYTHON" "$PACKAGE_INSTALL_DIR/bin/itstool.py" "\$@"
EOF
run chmod +x bin/itstool
    '
}

native_package_info_autoconf_archive() {
    PACKAGE_SRC_URL='https://ftp.gnu.org/gnu/autoconf-archive/autoconf-archive-2024.10.16.tar.xz'
    PACKAGE_SRC_SHA='7bcd5d001916f3a50ed7436f4f700e3d2b1bade3ed803219c592d62502a57363'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='configure'
}

native_package_info_netsurf_buildsystem() {
    PACKAGE_SRC_URL='https://download.netsurf-browser.org/libs/releases/buildsystem-1.10.tar.gz'
    PACKAGE_SRC_SHA='3d3e39d569e44677c4b179129bde614c65798e2b3e6253160239d1fd6eae4d79'
    PACKAGE_DEP_AUX='gmake'
    PACKAGE_INSTALL='gmake install "PREFIX=$PACKAGE_INSTALL_DIR"'
}

# }}}
##############################################################################
# {{{ __install_the_given_package

__install_the_given_package_onexit() {
    is_package_installed "$PACKAGE_SPEC" || {
        abort 1 "package installation failure: $PACKAGE_SPEC\n"

        if [ -n "$PACKAGE_WORKING_DIR"] && [ -d "$PACKAGE_WORKING_DIR"] ; then
            printf '%b\n' "${COLOR_RED}you would probably want to figure out want had happeded, please change to the working directory: $PACKAGE_WORKING_DIR${COLOR_OFF}"
        fi
    }
}

# Note: this function must run in a subshell
__install_the_given_package() {
    printf '%b\n' "${COLOR_PURPLE}>>> Installation ${COLOR_OFF}${COLOR_GREEN}${1}${COLOR_OFF}${COLOR_PURPLE} start${COLOR_OFF}"

    unset PACKAGE_WORKING_DIR

    trap __install_the_given_package_onexit EXIT

    STATIC_LIBRARY_SUFFIX=.a
    SHARED_LIBRARY_SUFFIX=.dylib

    #########################################################################################

    if [ "$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_ARCH" = "$NATIVE_PLATFORM_NAME-$NATIVE_PLATFORM_ARCH" ] ; then
        CROSS_COMPILING=0
    else
        CROSS_COMPILING=1
    fi

    #########################################################################################

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
        cat <<EOF
NATIVE_PLATFORM_KIND = $NATIVE_PLATFORM_KIND
NATIVE_PLATFORM_TYPE = $NATIVE_PLATFORM_TYPE
NATIVE_PLATFORM_NAME = $NATIVE_PLATFORM_NAME
NATIVE_PLATFORM_VERS = $NATIVE_PLATFORM_VERS
NATIVE_PLATFORM_ARCH = $NATIVE_PLATFORM_ARCH
NATIVE_PLATFORM_NCPU = $NATIVE_PLATFORM_NCPU
NATIVE_PLATFORM_EUID = $NATIVE_PLATFORM_EUID
NATIVE_PLATFORM_EGID = $NATIVE_PLATFORM_EGID

     TIMESTAMP_UNIX = $TIMESTAMP_UNIX

DEVELOPER_DIR       = $DEVELOPER_DIR
XCODE_VERSION       = $XCODE_VERSION

XCPKG_ARG0          = $XCPKG_ARG0
XCPKG_ARG1          = $XCPKG_ARG1
XCPKG_ARGV          = $XCPKG_ARGV
XCPKG_PATH          = $XCPKG_PATH
XCPKG_HOME          = $XCPKG_HOME
XCPKG_VERSION       = $XCPKG_VERSION
XCPKG_URL_TRANSFORM = $XCPKG_URL_TRANSFORM

          LOG_LEVEL = $LOG_LEVEL
            PROFILE = $PROFILE
     CCACHE_ENABLED = $CCACHE_ENABLED
    CROSS_COMPILING = $CROSS_COMPILING
   KEEP_SESSION_DIR = $KEEP_SESSION_DIR
EXPORT_COMPILE_COMMANDS_JSON = $EXPORT_COMPILE_COMMANDS_JSON
EOF
    fi

    #########################################################################################

    PACKAGE_FORMULA_FILEPATH="$SESSION_DIR/$PACKAGE_NAME.yml"

    step "load formula"

    if [ "$DUMP_FORMULA" = 1 ] ; then
        bat --language=yaml --paging=never "$PACKAGE_FORMULA_FILEPATH"
    fi

    __load_formula_of_the_given_package "$PACKAGE_NAME" "$PACKAGE_FORMULA_FILEPATH"

    #########################################################################################

    if [ "$PACKAGE_PKGTYPE" = exe ] && [ "$PACKAGE_SUPPORT_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        export XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE=1
    else
        unset  XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE
    fi

    #########################################################################################

    if [ "$PACKAGE_SUPPORT_BUILD_IN_PARALLEL" != 1 ] ; then
        BUILD_NJOBS=1
    fi

    if [ "$PACKAGE_LTOABLE" != 1 ] ; then
        ENABLE_LTO=0
    fi

    #########################################################################################

    PACKAGE_INSTALL_UTS=
    PACKAGE_INSTALL_UTS="$(date +%s)"

    PACKAGE_INSTALL_SHA=
    PACKAGE_INSTALL_SHA="$(
{
    sha256sum <<EOF
$PACKAGE_SPEC:$$:$PACKAGE_INSTALL_UTS
EOF
} | cut -d ' ' -f1)"

    #########################################################################################

    PACKAGE_WORKING_DIR="$SESSION_DIR/$PACKAGE_SPEC"
    PACKAGE_BSCRIPT_DIR="$PACKAGE_WORKING_DIR/src/$PACKAGE_BSCRIPT"
    PACKAGE_BSCRIPT_DIR="${PACKAGE_BSCRIPT_DIR%/}"
    PACKAGE_BCACHED_DIR="$PACKAGE_WORKING_DIR/src/_"
    PACKAGE_INSTALL_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$PACKAGE_INSTALL_SHA"

    #########################################################################################

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
        cat <<EOF
PACKAGE_WORKING_DIR = $PACKAGE_WORKING_DIR
PACKAGE_BSCRIPT_DIR = $PACKAGE_BSCRIPT_DIR
PACKAGE_BCACHED_DIR = $PACKAGE_BCACHED_DIR
PACKAGE_INSTALL_DIR = $PACKAGE_INSTALL_DIR
EOF
    fi

    #########################################################################################

    step "create the working directory and change to it"

    run install -d "$PACKAGE_WORKING_DIR"
    run         cd "$PACKAGE_WORKING_DIR"

    run install -d src/_ fix res bin lib include stub map

    #########################################################################################

    PACKAGE_INSTALLING_SRC_DIR="$PACKAGE_WORKING_DIR/src"
    PACKAGE_INSTALLING_FIX_DIR="$PACKAGE_WORKING_DIR/fix"
    PACKAGE_INSTALLING_RES_DIR="$PACKAGE_WORKING_DIR/res"
    PACKAGE_INSTALLING_BIN_DIR="$PACKAGE_WORKING_DIR/bin"
    PACKAGE_INSTALLING_LIB_DIR="$PACKAGE_WORKING_DIR/lib"
    PACKAGE_INSTALLING_INC_DIR="$PACKAGE_WORKING_DIR/include"

    #########################################################################################

    # https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/system.3.html
    if [ "$TARGET_PLATFORM_NAME" = iPhoneOS ] ; then
        cat > stub/system.c <<EOF
#ifndef STUB_SYSTEM_C
#define STUB_SYSTEM_C

#include <stdlib.h>
#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>

extern char **environ;

#ifdef __cplusplus
    extern "C" {
#endif

__attribute__((unused))
static int stub_system(const char * cmd) {
    char* const argv[4] = {(char*)"sh", (char*)"-c", (char*)cmd, NULL};
    pid_t pid;
    int status = posix_spawn(&pid, "/bin/sh", NULL, NULL, argv, environ);
    if (0 == status) {
        return waitpid(pid, &status, 0);
    }
    return status;
}

#define system(x) stub_system(x)

#ifdef __cplusplus
    }
#endif

#endif
EOF
    fi

    #########################################################################################

    unset RECURSIVE_DEPENDENT_PACKAGE_NAMES

    [ -n "$PACKAGE_DEP_PKG" ] && {
        step "calculate dependency list of $1"

        unset PACKAGE_NAME_STACK

        for item in $PACKAGE_DEP_PKG
        do
            if [ -z "$item" ] ; then
                PACKAGE_NAME_STACK="$item"
            else
                PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
            fi
        done

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) TOPE="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    TOPE="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            RECURSIVE_DEPENDENT_PACKAGE_NAMES2="$TOPE"

            for item in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
            do
                if [ "$item" != "$TOPE" ] ; then
                    RECURSIVE_DEPENDENT_PACKAGE_NAMES2="$RECURSIVE_DEPENDENT_PACKAGE_NAMES2 $item"
                fi
            done

            RECURSIVE_DEPENDENT_PACKAGE_NAMES="$RECURSIVE_DEPENDENT_PACKAGE_NAMES2"

            unset TOPE_UPPERCASE_UNDERSCORE
            TOPE_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$TOPE" | tr '@+-.' '_' | tr a-z A-Z)

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${TOPE_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$item" ] ; then
                    PACKAGE_NAME_STACK="$item"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
                fi
            done
        done

        printf '%s\n' "$RECURSIVE_DEPENDENT_PACKAGE_NAMES"
    }

    #########################################################################################

    unset RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS

    [ -n "$PACKAGE_DEP_PKG" ] && {
        for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
        do
            DEPENDENT_PACKAGE_INSTALL_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME"

            if [ -z "$RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS" ] ; then
                RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR"
            else
                RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS="$RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS
$DEPENDENT_PACKAGE_INSTALL_DIR"
            fi

            if [ "$CROSS_COMPILING" = 1 ] ; then
                DEPENDENT_PACKAGE_BINARY__DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/bin"

                if [ -d  "$DEPENDENT_PACKAGE_BINARY__DIR" ] ; then
                    PATH="$DEPENDENT_PACKAGE_BINARY__DIR:$PATH"
                fi

                DEPENDENT_PACKAGE_BINARY__DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/sbin"

                if [ -d  "$DEPENDENT_PACKAGE_BINARY__DIR" ] ; then
                    PATH="$DEPENDENT_PACKAGE_BINARY__DIR:$PATH"
                fi

                if [ -d          "$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/share/aclocal" ] ; then
                    ACLOCAL_PATH="$NATIVE_PACKAGE_INSTALLED_ROOT/$DEPENDENT_PACKAGE_NAME/share/aclocal:$ACLOCAL_PATH"
                fi
            else
                DEPENDENT_PACKAGE_BINARY__DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/bin"

                if [ -d  "$DEPENDENT_PACKAGE_BINARY__DIR" ] ; then
                    PATH="$DEPENDENT_PACKAGE_BINARY__DIR:$PATH"
                fi

                DEPENDENT_PACKAGE_BINARY__DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/sbin"

                if [ -d  "$DEPENDENT_PACKAGE_BINARY__DIR" ] ; then
                    PATH="$DEPENDENT_PACKAGE_BINARY__DIR:$PATH"
                fi
            fi
        done
    }

    #########################################################################################

    [ -n "$PACKAGE_DEP_PKG" ] && {
        step "generate  dependency tree of $1"

        unset DOT_CONTENT
        unset D2__CONTENT

        STACK="$PACKAGE_NAME"

        while [ -n "$STACK" ]
        do
            case $STACK in
                *\;*) TOPE="${STACK##*;}" ; STACK="${STACK%;*}" ;;
                *)    TOPE="${STACK}"     ; STACK=
            esac

            unset TOPE_UPPERCASE_UNDERSCORE
            TOPE_UPPERCASE_UNDERSCORE=$(printf '%s\n' "$TOPE" | tr '@+-.' '_' | tr a-z A-Z)

            TOPE_DEP_PKG="$(eval echo \$PACKAGE_DEP_PKG_"${TOPE_UPPERCASE_UNDERSCORE}")"

            if [ -n "$TOPE_DEP_PKG" ] ; then
                unset X; X="$(printf '"%s" ' $TOPE_DEP_PKG)"
                unset Y; Y="$(printf '    "%s" -> { %s}\n' "$TOPE" "$X")"

                if [ -z "$DOT_CONTENT" ] ; then
                    DOT_CONTENT="$Y"
                else
                    DOT_CONTENT="$(printf '%s\n%s\n' "$DOT_CONTENT" "$Y")"
                fi
            fi

            for item in $TOPE_DEP_PKG
            do
                if [ -z "$D2__CONTENT" ] ; then
                    D2__CONTENT="$TOPE -> $item"
                else
                    D2__CONTENT="$D2__CONTENT
$TOPE -> $item"
                fi

                if [ -z "$item" ] ; then
                    STACK="$item"
                else
                    STACK="$STACK;$item"
                fi
            done
        done

        DOT_CONTENT="digraph G {
$DOT_CONTENT
}"

        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

        PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_="$PACKAGE_WORKING_DIR/dependencies.d2"
        PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT="$PACKAGE_WORKING_DIR/dependencies.dot"
        PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX="$PACKAGE_WORKING_DIR/dependencies.box"

        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

        printf '%s\n' "$D2__CONTENT" > "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_"
        printf '%s\n' "$DOT_CONTENT" > "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT"

        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

        # https://github.com/ggerganov/dot-to-ascii
        curl \
            -o "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX" \
            -s \
            -G \
            --data-urlencode "boxart=1" \
            --data-urlencode "src=$DOT_CONTENT" \
            "https://dot-to-ascii.ggerganov.com/dot-to-ascii.php" || true

        #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#

        DOT="$(command -v dot || command -v dot_static || true)"

        if [ -n "$DOT" ] ; then
            run "$DOT" -Tsvg -o "$PACKAGE_WORKING_DIR/dependencies.svg" "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT" || true
        else
            D2="$(command -v d2 || true)"

            if [ -n "$D2" ] ; then
                run "$D2" "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_D2_" "$PACKAGE_WORKING_DIR/dependencies.svg"
            fi
        fi

        ############################################################################

        if [ -f "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX" ] ; then
            cat "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_BOX"
        else
            cat "$PACKAGE_DEPENDENCY_GRAPH_FILEPATH_DOT"
        fi
    }

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_GMAKE" = 1 ] && [ "$EXPORT_COMPILE_COMMANDS_JSON" = 1 ] && [ "$BEAR_ENABLED" = 1 ] ; then
        PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP bear"
    fi

    if [ "$CCACHE_ENABLED" = 1 ] ; then
        PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP ccache"
    fi

    #########################################################################################

    unset PACKAGE_DEP_AUX_LIBZ
    unset PACKAGE_DEP_AUX_LIBOPENSSL

    # these native packages would be built from source locally due to they are not relocatable or libraries
    unset PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY

    #########################################################################################

    step "install needed packages via uppm"

    run "$UPPM" about
    run "$UPPM" update

    PACKAGE_DEP_AUX="$PACKAGE_DEP_UPP"
    PACKAGE_DEP_UPP=

    for UPPM_PACKAGE_NAME in $PACKAGE_DEP_AUX
    do
        case $UPPM_PACKAGE_NAME in
            libz)
                PACKAGE_DEP_AUX_LIBZ=1
                PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY libz"
                ;;
            libopenssl)
                PACKAGE_DEP_AUX_LIBOPENSSL=1
                PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY libopenssl"
                ;;
            automake)
                PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY autoconf automake"
                PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl gmake gm4"
                ;;
            autoconf|libtool|texinfo|help2man|intltool)
                PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY $UPPM_PACKAGE_NAME"
                PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl gmake gm4"
                ;;
            itstool)
                PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY itstool"
                PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP perl python3"
                ;;
            autoconf-archive)
                PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY autoconf_archive"
                ;;
            netsurf_buildsystem)
                PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY="$PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY $UPPM_PACKAGE_NAME"
                ;;
            *)  PACKAGE_DEP_UPP="$PACKAGE_DEP_UPP $UPPM_PACKAGE_NAME"
        esac
    done

    ####################################################################

    unset UPPM_INSTALL_ARGS

    if [ "$DUMP_UPPM" = 1 ] ; then
        UPPM_INSTALL_ARGS=-v
    fi

    ####################################################################

    for UPPM_PACKAGE_NAME in $PACKAGE_DEP_UPP pkg-config tree
    do
        run "$UPPM" install "$UPPM_PACKAGE_NAME" $UPPM_INSTALL_ARGS

        UPPM_PACKAGE_INSTALLED_DIR="$UPPM_HOME/installed/$UPPM_PACKAGE_NAME"

        if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then
            PATH="$UPPM_PACKAGE_INSTALLED_DIR/bin:$PATH"
        fi

        if [ -d  "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            PATH="$UPPM_PACKAGE_INSTALLED_DIR/sbin:$PATH"
        fi

        if [ -d          "$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
            ACLOCAL_PATH="$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH"
        fi

        for d in lib share
        do
            UPPM_PACKAGE_PKGCONF_DIR="$UPPM_PACKAGE_INSTALLED_DIR/$d/pkgconfig"

            if [ -d "$UPPM_PACKAGE_PKGCONF_DIR" ] ; then
                PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$UPPM_PACKAGE_PKGCONF_DIR"
                break
            fi
        done

        case $UPPM_PACKAGE_NAME in
            swig)
                # https://www.swig.org/Doc4.0/Library.html
                X="$(ls $UPPM_PACKAGE_INSTALLED_DIR/share/swig/*/swig.swg)"
                export SWIG_LIB="${X%/*}"
                ;;
            file)
                export MAGIC="$UPPM_PACKAGE_INSTALLED_DIR/share/misc/magic.mgc"
                ;;
            docbook-xsl)
                # http://xmlsoft.org/xslt/xsltproc.html
                export XML_CATALOG_FILES="$UPPM_PACKAGE_INSTALLED_DIR/catalog.xml"
                printf '%s\n' "XML_CATALOG_FILES=$XML_CATALOG_FILES"
        esac
    done

    #########################################################################################

    for NATIVE_PACKAGE_NAME in $PACKAGE_DEP_AUX_NEED_TO_BUILD_LOCALLY
    do
        (install_the_given_native_package "$NATIVE_PACKAGE_NAME")

        NATIVE_PACKAGE_INSTALLED_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$NATIVE_PACKAGE_NAME"

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/include" ] ; then
            CPPFLAGS_FOR_BUILD="$CPPFLAGS_FOR_BUILD -I$NATIVE_PACKAGE_INSTALLED_DIR/include"
        fi

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/lib" ] ; then
            LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -L$NATIVE_PACKAGE_INSTALLED_DIR/lib -Wl,-rpath,$NATIVE_PACKAGE_INSTALLED_DIR/lib"
        fi

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/bin" ] ; then
            PATH="$NATIVE_PACKAGE_INSTALLED_DIR/bin:$PATH"
        fi

        if [ -d  "$NATIVE_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            PATH="$NATIVE_PACKAGE_INSTALLED_DIR/sbin:$PATH"
        fi

        if [ -d          "$NATIVE_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
            ACLOCAL_PATH="$NATIVE_PACKAGE_INSTALLED_DIR/share/aclocal:$ACLOCAL_PATH"
        fi

        for d in lib share
        do
            NATIVE_PACKAGE_PKGCONF_DIR="$NATIVE_PACKAGE_INSTALLED_DIR/$d/pkgconfig"

            if [ -d "$NATIVE_PACKAGE_PKGCONF_DIR" ] ; then
                PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$NATIVE_PACKAGE_PKGCONF_DIR"
                break
            fi
        done
    done

    #########################################################################################

    [ -n "$PACKAGE_DEP_PYM" ] && {
        step "install needed python packages via pip"

        PYTHON3="$(command -v python3)" || abort 1 "command not found: python3"

        run "$PYTHON3" --version
        run "$PYTHON3" -m pip install --upgrade pip
        run "$PYTHON3" -m pip install --upgrade "$PACKAGE_DEP_PYM"
    }

    #########################################################################################

    # cpan use the C/C++ compiler same as perl was built with
    # so make sure C/C++ compiler be found before reaching here

    [ -n "$PACKAGE_DEP_PLM" ] && {
        step "install needed perl modules via cpan"

        unset PACKAGE_DEP_PLM_T1
        unset PACKAGE_DEP_PLM_T2

        for item in $PACKAGE_DEP_PLM
        do
            if [ "$item" = 'XML::Parser' ] ; then
                PACKAGE_DEP_PLM_T1='XML::Parser'
            else
                PACKAGE_DEP_PLM_T2="$PACKAGE_DEP_PLM_T2 $item"
            fi
        done

        if [ -n "$PACKAGE_DEP_PLM_T1" ] ; then
            (install_the_given_native_package perl_XML_Parser)
        fi

        if [ -n "$PACKAGE_DEP_PLM_T2" ] ; then
            PACKAGE_DEP_PLM_T2="${PACKAGE_DEP_PLM_T2# }"
        fi

        if [ -n "$PACKAGE_DEP_PLM_T2" ] ; then
            # Would you like to configure as much as possible automatically? [yes]
            # https://perldoc.perl.org/cpan#PERL_MM_USE_DEFAULT
            export PERL_MM_USE_DEFAULT=1
            run cpan "$PACKAGE_DEP_PLM_T2"
        fi

        if [ -d "$HOME/perl5/bin" ] ; then
            # cpan install to default local location
            bppend_to_PATH "$HOME/perl5/bin"
        fi
    }

    #########################################################################################

    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && {
        command -v rustup > /dev/null || {
            # https://www.rust-lang.org/tools/install
            note "${COLOR_GREEN}rustup cargo rustc${COLOR_OFF} ${COLOR_YELLOW}commands are required, but it was not found, let's install it.${COLOR_OFF}"

            RUST_INIT_SH_FILEPATH="$PACKAGE_WORKING_DIR/rustup-init.sh"

            wfetch 'https://sh.rustup.rs' -o rustup-init.sh

            run bash "$RUST_INIT_SH_FILEPATH" -y

            export CARGO_HOME="$HOME/.cargo"
            export PATH="$CARGO_HOME/bin:$PATH"
        }
    }

    #########################################################################################

    step "locate needed tools"

    unset AUTORECONF
    unset AUTOCONF
    unset AUTOMAKE
    unset ACLOCAL
    unset M4

    unset MESON
    unset CMAKE
    unset XMAKE
    unset GMAKE
    unset NINJA

    unset BEAR
    unset CCACHE
    unset PKG_CONFIG

    [ -n "$PACKAGE_DEP_UPP" ] && [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] && {
        for item in $PACKAGE_DEP_UPP
        do
            case $item in
                curl)   run curl --version ;;
                git)    run git  --version ;;
                gtar)   run tar  --version ;;
                gzip)   run gzip --version ;;
                xz)     run xz   --version ;;
                patch)  run patch --version ;;
                perl)   run perl --version ;;
                python3)run python3 --version ;;
            esac
        done
    }

    {
        [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] ||
        [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ]
    } && {
        AUTORECONF=$(command -v autoreconf) || abort 1 "command not found: autoreconf"
        AUTOCONF=$(command -v autoconf)     || abort 1 "command not found: autoconf"
        AUTOMAKE=$(command -v automake)     || abort 1 "command not found: automake"
        ACLOCAL=$(command -v aclocal)       || abort 1 "command not found: aclocal"
        M4=$(command -v m4)                 || abort 1 "command not found: m4"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$AUTORECONF" --version
            printf '\n'
            run "$AUTOCONF"   --version
            printf '\n'
            run "$AUTOMAKE"   --version
            printf '\n'
            run "$ACLOCAL"    --version
            printf '\n'
            run "$M4"         --version
            printf '\n'
        fi
    }

    [ "$PACKAGE_USE_BSYSTEM_MESON" = 1 ] && {
        MESON=$(command -v meson) || abort 1 "command not found: meson"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$MESON"      --version
            printf '\n'
        fi
    }

    [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] && {
        CMAKE=$(command -v cmake) || abort 1 "command not found: cmake"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$CMAKE"      --version
            printf '\n'
        fi
    }

    [ "$PACKAGE_USE_BSYSTEM_XMAKE" = 1 ] && {
        XMAKE=$(command -v xmake) || abort 1 "command not found: xmake"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$XMAKE"      --version
            printf '\n'
        fi
    }

    [ "$PACKAGE_USE_BSYSTEM_GMAKE" = 1 ] && {
        GMAKE=$(command -v gmake || command -v make) || abort 1 "command not found: gmake and make"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$GMAKE"      --version
            printf '\n'
        fi
    }

    [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] && {
        NINJA=$(command -v ninja) || abort 1 "command not found: ninja"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$NINJA"      --version
            printf '\n'
        fi
    }

    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && {
        RUSTUP=$(command -v rustup) || abort 1 "command not found: rustup"
        CARGO=$(command -v cargo)   || abort 1 "command not found: cargo"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$RUSTUP"     --version
            printf '\n'
            run "$CARGO"      --version
            printf '\n'
        fi
    }

    [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] && {
        GO=$(command -v go) || abort 1 "command not found: go"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$GO"      version
            printf '\n'
        fi
    }

    [ "$CCACHE_ENABLED" = 1 ] && {
        CCACHE=$(command -v ccache) || abort 1 "command not found: ccache"

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            run "$CCACHE"    --version
            printf '\n'
        fi
    }

    PKG_CONFIG=$(command -v pkg-config || command -v pkgconf) || abort 1 "command not found: pkg-config"

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
        run "$PKG_CONFIG"    --version
        printf '\n'
    fi

    unset  M4
    export M4="$(command -v m4 || true)"

    #########################################################################################

    step "dofetch"

    if [ -n "$PACKAGE_DOFETCH" ] ; then
        eval "
dofetch() {
$PACKAGE_DOFETCH
}"
        dofetch
    else
        case $PACKAGE_SRC_URL in
            '')
                if [ -n "$PACKAGE_GIT_URL" ] ; then
                    unset GIT_FETCH_URL

                    if [ -z "$XCPKG_URL_TRANSFORM" ] ; then
                        GIT_FETCH_URL="$PACKAGE_GIT_URL"
                    else
                        GIT_FETCH_URL="$("$XCPKG_URL_TRANSFORM" "$PACKAGE_GIT_URL")" || return 1
                    fi

                    if [ -z "$PACKAGE_GIT_SHA" ] ; then
                        if [ -z "$PACKAGE_GIT_REF" ] ; then
                            GIT_BRANCH_NAME=master
                            GIT_REF_SPEC="+HEAD:refs/remotes/origin/master"
                        else
                            GIT_BRANCH_NAME="${PACKAGE_GIT_REF##*/}"
                            GIT_REF_SPEC="+$PACKAGE_GIT_REF:refs/remotes/origin/$GIT_BRANCH_NAME"
                        fi
                    else
                        GIT_BRANCH_NAME=master
                        GIT_REF_SPEC="+$PACKAGE_GIT_SHA:refs/remotes/origin/master"
                    fi

                    if [ -z "$PACKAGE_GIT_NTH" ] ; then
                        PACKAGE_GIT_NTH=1
                    fi

                    if [ "$PACKAGE_GIT_NTH" -eq 0 ] ; then
                        if [ -f "$PACKAGE_SRC_FILEPATH/.git/shallow" ] ; then
                            GIT_FETCH_EXTRA_OPTIONS='--unshallow'
                        else
                            GIT_FETCH_EXTRA_OPTIONS=
                        fi
                    else
                        GIT_FETCH_EXTRA_OPTIONS="--depth=$PACKAGE_GIT_NTH"
                    fi

                    run cd "$PACKAGE_INSTALLING_SRC_DIR"
                    run git -c init.defaultBranch=master init
                    run git remote add origin "$GIT_FETCH_URL"
                    run git -c protocol.version=2 fetch --progress $GIT_FETCH_EXTRA_OPTIONS origin "$GIT_REF_SPEC"
                    run git checkout --progress --force -B "$GIT_BRANCH_NAME" "refs/remotes/origin/$GIT_BRANCH_NAME"

                    git_submodule_update_recursive
                fi
                ;;
            dir://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                ;;
            file://*)
                note "$PACKAGE_SRC_URL is local path, no need to fetch."
                ;;
            *)  wfetch "$PACKAGE_SRC_URL" --uri="$PACKAGE_SRC_URI" --sha256="$PACKAGE_SRC_SHA" -o "$PACKAGE_SRC_FILEPATH"
        esac

        if [ -n    "$PACKAGE_FIX_URL" ] ; then
            wfetch "$PACKAGE_FIX_URL" --uri="$PACKAGE_FIX_URI" --sha256="$PACKAGE_FIX_SHA" -o "$PACKAGE_FIX_FILEPATH"
        fi

        if [ -n    "$PACKAGE_RES_URL" ] ; then
            wfetch "$PACKAGE_RES_URL" --uri="$PACKAGE_RES_URI" --sha256="$PACKAGE_RES_SHA" -o "$PACKAGE_RES_FILEPATH"
        fi

        #########################################################################################

        step "unpack/copy resources"

        if [ -n "$PACKAGE_SRC_FILEPATH" ] ; then
            case $PACKAGE_SRC_FILETYPE in
                .dir)
                    if [ -d "$PACKAGE_SRC_FILEPATH" ] ; then
                        if [ -d "$PACKAGE_SRC_FILEPATH/.git" ] && command -v git > /dev/null ; then
                            PACKAGE_GIT_SHA=$(git -C "$PACKAGE_SRC_FILEPATH" rev-parse HEAD || true)
                        fi
                        run cp -r "$PACKAGE_SRC_FILEPATH/." "$PACKAGE_INSTALLING_SRC_DIR"
                    else
                        abort 1 "src-url point to dir '$PACKAGE_SRC_FILEPATH' does not exist."
                    fi
                    ;;
                .git)
                    if [ -z "$PACKAGE_GIT_SHA" ] ; then
                        PACKAGE_GIT_SHA="$(git rev-parse HEAD)"
                    fi
                    ;;
                .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                    run bsdtar xf "$PACKAGE_SRC_FILEPATH" -C "$PACKAGE_INSTALLING_SRC_DIR" --strip-components 1 --no-same-owner
                    ;;
                *)  run cp "$PACKAGE_SRC_FILEPATH" "$PACKAGE_INSTALLING_SRC_DIR/"
            esac
        fi

        if [ -n "$PACKAGE_FIX_FILEPATH" ] ; then
            case $PACKAGE_FIX_FILETYPE in
                .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                    run bsdtar xf "$PACKAGE_FIX_FILEPATH" -C "$PACKAGE_INSTALLING_FIX_DIR" --strip-components 1 --no-same-owner
                    ;;
                *)  run cp "$PACKAGE_FIX_FILEPATH" "$PACKAGE_INSTALLING_FIX_DIR/"
                    printf '%s|%s\n' "$PACKAGE_FIX_FILENAME" "$PACKAGE_FIX_OPT" > "$PACKAGE_INSTALLING_FIX_DIR/index"
            esac
        fi

        if [ -n "$PACKAGE_RES_FILEPATH" ] ; then
            case $PACKAGE_RES_FILETYPE in
                .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                    run bsdtar xf "$PACKAGE_RES_FILEPATH" -C "$PACKAGE_INSTALLING_RES_DIR" --strip-components 1 --no-same-owner
                    ;;
                *)  run cp "$PACKAGE_RES_FILEPATH" "$PACKAGE_INSTALLING_RES_DIR/"
            esac
        fi

        for LINE in $PACKAGE_PATCHES
        do
            SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
            URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"
            URI="$(printf '%s\n' "$LINE" | cut -d '|' -f3)"
            OPT="$(printf '%s\n' "$LINE" | cut -d '|' -f4)"

            FILETYPE="$(filetype_from_url "$URL")"
            FILENAME="$SHA$FILETYPE"
            FILEPATH="$XCPKG_DOWNLOADS_DIR/$FILENAME"

            wfetch "$URL" --uri="$URI" --sha256="$SHA" -o "$FILEPATH"

            case $FILETYPE in
                .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                    run bsdtar xf "$FILEPATH" -C "$PACKAGE_INSTALLING_FIX_DIR" --strip-components 1 --no-same-owner
                    ;;
                *)  run cp "$FILEPATH" "$PACKAGE_INSTALLING_FIX_DIR/"
                    printf '%s|%s\n' "$FILENAME" "$OPT" >> "$PACKAGE_INSTALLING_FIX_DIR/index"
            esac
        done

        for LINE in $PACKAGE_RESLIST
        do
            SHA="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
            URL="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"
            URI="$(printf '%s\n' "$LINE" | cut -d '|' -f3)"
            DIR="$(printf '%s\n' "$LINE" | cut -d '|' -f4)"
            LEV="$(printf '%s\n' "$LINE" | cut -d '|' -f5)"

            [ -z "$LEV" ] && LEV=1

            FILETYPE="$(filetype_from_url "$URL")"
            FILENAME="$SHA$FILETYPE"
            FILEPATH="$XCPKG_DOWNLOADS_DIR/$FILENAME"

            wfetch "$URL" --uri="$URI" --sha256="$SHA" -o "$FILEPATH"

            if [ -z "$DIR" ] ; then
                DEST="$PACKAGE_INSTALLING_RES_DIR"
            else
                DEST="$PACKAGE_INSTALLING_RES_DIR/$DIR"
                run install -d "$DEST"
            fi

            case $FILETYPE in
                .zip|.txz|.tgz|.tlz|.tbz2|.crate)
                    run bsdtar xf "$FILEPATH" -C "$DEST" --strip-components "$LEV" --no-same-owner
                    ;;
                *)  run cp "$FILEPATH" "$DEST/"
            esac
        done
    fi

    #########################################################################################

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
        step "tree files of the installing top directory"
        run tree --dirsfirst -L 2 "$PACKAGE_WORKING_DIR"

        step "list files of the installing src directory"
        run ls -l "$PACKAGE_INSTALLING_SRC_DIR"

        if [ -n "$PACKAGE_BSCRIPT" ] ; then
            step "list files of the installing build script directory"
            run ls -l "$PACKAGE_BSCRIPT_DIR"
        fi
    fi

    #########################################################################################

    if [ -n "$PACKAGE_DO12345" ] ; then
        step "build for native"

        NATIVE_BUILD_NEEDED=1

        NATIVE_INSTALLED_VERSION_TXT_FILEPATH="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME/version.txt"

        [ -f "$NATIVE_INSTALLED_VERSION_TXT_FILEPATH" ] && {
            if [ "$(cat "$NATIVE_INSTALLED_VERSION_TXT_FILEPATH")" = "$PACKAGE_VERSION" ] ; then
                NATIVE_BUILD_NEEDED=0
                note "build for native already have been done, skipped."
            else
                note "build for native already have been done, but not the same version, rebuild it."
            fi
        }

        if [ "$NATIVE_BUILD_NEEDED" = 1 ] ; then
            NATIVE_BCACHED_DIR="$PACKAGE_WORKING_DIR/src/-"
            NATIVE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_INSTALL_SHA"

            cat <<EOF
NATIVE_BCACHED_DIR = $NATIVE_BCACHED_DIR
NATIVE_INSTALL_DIR = $NATIVE_INSTALL_DIR
EOF

            (
                PACKAGE_BCACHED_DIR="$NATIVE_BCACHED_DIR"
                PACKAGE_INSTALL_DIR="$NATIVE_INSTALL_DIR"

                run install -d "$PACKAGE_BCACHED_DIR"

                if [ "$PACKAGE_BINBSTD" = 1 ] ; then
                    run cd "$PACKAGE_BSCRIPT_DIR"
                else
                    run cd "$PACKAGE_BCACHED_DIR"
                fi

                eval "
build_for_native() {
$PACKAGE_DO12345
}"

                [ "$DUMP_ENV" = 1 ] && {
                    run export -p
                    printf '\n'
                }

                BUILD_FOR_NATIVE=1

                build_for_native
            )

            [ -d "$NATIVE_INSTALL_DIR" ] && {
                printf '%s\n' "$PACKAGE_VERSION" > "$NATIVE_INSTALL_DIR/version.txt"
                run ln -s -r -f -T "$NATIVE_INSTALL_DIR" "$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME"
            }
        else
            NATIVE_INSTALL_DIR="$NATIVE_PACKAGE_INSTALLED_ROOT/$PACKAGE_NAME"
        fi

        [ -d "$NATIVE_INSTALL_DIR" ] && {
            if [ -d  "$NATIVE_INSTALL_DIR/bin" ] ; then
                PATH="$NATIVE_INSTALL_DIR/bin:$PATH"
            fi

            if [ -d  "$NATIVE_INSTALL_DIR/sbin" ] ; then
                PATH="$NATIVE_INSTALL_DIR/sbin:$PATH"
            fi

            if [ -d          "$NATIVE_INSTALL_DIR/share/aclocal" ] ; then
                ACLOCAL_PATH="$NATIVE_INSTALL_DIR/share/aclocal:$ACLOCAL_PATH"
            fi
        }
    fi

    ##################################################################################

         CC="$XCPKG_CORE_DIR/wrapper-target-cc"
        CXX="$XCPKG_CORE_DIR/wrapper-target-c++"
       OBJC="$XCPKG_CORE_DIR/wrapper-target-objc"
        CPP="$CC -E"
         AS="$XCODE_AS"
         AR="$XCODE_AR"
     RANLIB="$XCODE_RANLIB"
         LD="$XCODE_LD"
         NM="$XCODE_NM"
       SIZE="$XCODE_SIZE"
      STRIP="$XCODE_STRIP"
    STRINGS="$XCODE_STRINGS"
    OBJDUMP="$XCODE_OBJDUMP"

    eval "SYSROOT=\"\$XCODE_${TARGET_PLATFORM_NAME}_SDKROOT\""

    ##################################################################################

    for TOOL in CC OBJC CXX CPP AS AR RANLIB LD NM STRIP SIZE STRINGS OBJDUMP SYSROOT
    do
        export "$TOOL"
    done

    ##################################################################################

    TARGET_PLATFORM_NAME_LOWER_CASE="$(printf "$TARGET_PLATFORM_NAME" | tr A-Z a-z)"

    export XCPKG_TARGET_FLAGS="-isysroot $SYSROOT -arch $TARGET_PLATFORM_ARCH -m${TARGET_PLATFORM_NAME_LOWER_CASE}-version-min=$TARGET_PLATFORM_VERS -Qunused-arguments"

    ##################################################################################

    PPFLAGS="$PACKAGE_PPFLAGS"
    CCFLAGS="$PACKAGE_CCFLAGS"
    OCFLAGS="$PACKAGE_OCFLAGS"
    OXFLAGS="$PACKAGE_OXFLAGS"
    XXFLAGS="$PACKAGE_XXFLAGS"
    LDFLAGS="$PACKAGE_LDFLAGS -Wl,-search_paths_first"

    ##############################################

    if [ "$DEBUG_CC" = 1 ] ; then
        CCFLAGS="$CCFLAGS -v"
        XXFLAGS="$XXFLAGS -v"
        OCFLAGS="$OCFLAGS -v"
        OXFLAGS="$OXFLAGS -v"
    fi

    if [ "$DEBUG_LD" = 1 ] ; then
        LDFLAGS="$LDFLAGS -Wl,-v"
    fi

    ##############################################

    case $PROFILE in
        debug)
            CCFLAGS="$CCFLAGS -O0 -g"
            XXFLAGS="$XXFLAGS -O0 -g"
            OCFLAGS="$OCFLAGS -O0 -g"
            OXFLAGS="$OXFLAGS -O0 -g"
            ;;
        release)
            CCFLAGS="$CCFLAGS -Os"
            XXFLAGS="$XXFLAGS -Os"
            OCFLAGS="$OCFLAGS -Os"
            OXFLAGS="$OXFLAGS -Os"
            LDFLAGS="$LDFLAGS -Wl,-S"

            unset _U_NDEBUG_OPT_IS_SET

            for item in $PACKAGE_PPFLAGS
            do
                [ "$item" = '-UNDEBUG' ] && {
                    _U_NDEBUG_OPT_IS_SET=1
                    break
                }
            done

            if [ "$_U_NDEBUG_OPT_IS_SET" != 1 ] ; then
                PPFLAGS="$PPFLAGS -DNDEBUG"
            fi

            if [ -z "$ENABLE_LTO" ] || [ "$ENABLE_LTO" = 1 ] ; then
                LDFLAGS="$LDFLAGS -flto"
            fi
    esac


    ##############################################

    _F_COMMON_OPT_IS_SET=0

    for item in $CCFLAGS
    do
        [ "$item" = '-fcommon' ] && {
            _F_COMMON_OPT_IS_SET=1
            break
        }
    done

    if [ "$_F_COMMON_OPT_IS_SET" = 0 ] ; then
        CCFLAGS="$CCFLAGS -fno-common"
    fi

    ##############################################

    _F_COMMON_OPT_IS_SET=0

    for item in $OCFLAGS
    do
        [ "$item" = '-fcommon' ] && {
            _F_COMMON_OPT_IS_SET=1
            break
        }
    done

    if [ "$_F_COMMON_OPT_IS_SET" = 0 ] ; then
        OCFLAGS="$OCFLAGS -fno-common"
    fi

    ##############################################

    _F_COMMON_OPT_IS_SET=0

    for item in $OXFLAGS
    do
        [ "$item" = '-fcommon' ] && {
            _F_COMMON_OPT_IS_SET=1
            break
        }
    done

    if [ "$_F_COMMON_OPT_IS_SET" = 0 ] ; then
        OXFLAGS="$OXFLAGS -fno-common"
    fi

    ##############################################

    _F_COMMON_OPT_IS_SET=0

    for item in $XXFLAGS
    do
        [ "$item" = '-fcommon' ] && {
            _F_COMMON_OPT_IS_SET=1
            break
        }
    done

    if [ "$_F_COMMON_OPT_IS_SET" = 0 ] ; then
        XXFLAGS="$XXFLAGS -fno-common"
    fi

    ##############################################

    for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
    do
        DEPENDENT_PACKAGE_NAME_UNDERSCORE="$(printf '%s\n' "$DEPENDENT_PACKAGE_NAME" | tr '@+-.' '_')"

        DEPENDENT_PACKAGE_INSTALL_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME"
        DEPENDENT_PACKAGE_INCLUDE_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/include"
        DEPENDENT_PACKAGE_LIBRARY_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib"
        DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib/pkgconfig"

        eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_INSTALL_DIR='$DEPENDENT_PACKAGE_INSTALL_DIR'"
        eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_INCLUDE_DIR='$DEPENDENT_PACKAGE_INCLUDE_DIR'"
        eval "${DEPENDENT_PACKAGE_NAME_UNDERSCORE}_LIBRARY_DIR='$DEPENDENT_PACKAGE_LIBRARY_DIR'"

        if [ -d "$DEPENDENT_PACKAGE_INCLUDE_DIR" ] ; then
            PPFLAGS="-I$DEPENDENT_PACKAGE_INCLUDE_DIR $PPFLAGS"
        fi

        if [ -d "$DEPENDENT_PACKAGE_LIBRARY_DIR" ] ; then
            LDFLAGS="-L$DEPENDENT_PACKAGE_LIBRARY_DIR -Wl,-rpath,$DEPENDENT_PACKAGE_LIBRARY_DIR $LDFLAGS"
        fi
    done

    PPFLAGS="-I$PACKAGE_INSTALLING_INC_DIR $PPFLAGS"
    LDFLAGS="-L$PACKAGE_INSTALLING_LIB_DIR $LDFLAGS"

    export    CFLAGS="$CCFLAGS"
    export OBJCFLAGS="$OCFLAGS"
    export  CXXFLAGS="$XXFLAGS"
    export  CPPFLAGS="$PPFLAGS"
    export   LDFLAGS="$LDFLAGS"

    #########################################################################################

    # https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
    export XDG_DATA_DIRS

    for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS
    do
        # https://gi.readthedocs.io/en/latest/tools/g-ir-scanner.html#environment-variables
        if [ -d "$DEPENDENT_PACKAGE_INSTALL_DIR/share/gir-1.0" ] ; then
            if [ -z "$XDG_DATA_DIRS" ] ; then
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share"
            else
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share:$XDG_DATA_DIRS"
            fi
        fi

        # https://help.gnome.org/admin//system-admin-guide/2.32/mimetypes-database.html.en
        if [ -d "$DEPENDENT_PACKAGE_INSTALL_DIR/share/mime" ] ; then
            if [ -z "$XDG_DATA_DIRS" ] ; then
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share"
            else
                XDG_DATA_DIRS="$DEPENDENT_PACKAGE_INSTALL_DIR/share:$XDG_DATA_DIRS"
            fi
        fi
    done

    #########################################################################################

    # https://www.gnu.org/software/automake/manual/html_node/Macro-Search-Path.html
    export ACLOCAL_PATH

    for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS
    do
        DEPENDENT_PACKAGE_ACLOCAL_PATH="$DEPENDENT_PACKAGE_INSTALL_DIR/share/aclocal"

        if [ -d "$DEPENDENT_PACKAGE_ACLOCAL_PATH" ] ; then
            if [ -z "$ACLOCAL_PATH" ] ; then
                ACLOCAL_PATH="$DEPENDENT_PACKAGE_ACLOCAL_PATH"
            else
                ACLOCAL_PATH="$DEPENDENT_PACKAGE_ACLOCAL_PATH:$ACLOCAL_PATH"
            fi
        fi
    done

    #########################################################################################

    PATH="$PACKAGE_INSTALLING_BIN_DIR:$PATH"

    #########################################################################################

    # https://www.freedesktop.org/wiki/Software/pkg-config/CrossCompileProposal
    unset PKG_CONFIG_SYSROOT_DIR

    if [ "$DEBUG_PKG_CONFIG" = 1 ] ; then
        export PKG_CONFIG_DEBUG_SPEW='set'
    fi

    # override the default search directory (usually /usr/lib/pkgconfig:/usr/share/pkgconfig)
    # because we only want to use our own
    export PKG_CONFIG_LIBDIR="$PACKAGE_WORKING_DIR/lib/pkgconfig"

    if [ -z "$PKG_CONFIG_PATH" ] ; then
        export PKG_CONFIG_PATH="$PACKAGE_WORKING_DIR/lib/pkgconfig"
    else
        export PKG_CONFIG_PATH="$PACKAGE_WORKING_DIR/lib/pkgconfig:$PKG_CONFIG_PATH"
    fi

    for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS
    do
        DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib/pkgconfig"

        if [ -d "$DEPENDENT_PACKAGE_PKGCONF_DIR" ] ; then
            PKG_CONFIG_PATH="$DEPENDENT_PACKAGE_PKGCONF_DIR:$PKG_CONFIG_PATH"
        else
            DEPENDENT_PACKAGE_PKGCONF_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/share/pkgconfig"

            if [ -d "$DEPENDENT_PACKAGE_PKGCONF_DIR" ] ; then
                PKG_CONFIG_PATH="$DEPENDENT_PACKAGE_PKGCONF_DIR:$PKG_CONFIG_PATH"
            fi
        fi
    done

    #########################################################################################

    unset XCPKG_TARGET_LDFLAGS
    unset XCPKG_TARGET_CCFLAGS
    unset XCPKG_TARGET_CXXFLAGS
    unset XCPKG_TARGET_OBJCFLAGS

    for item in $PACKAGE_DEP_LIB
    do
        case $item in
            -l*);;
            *)
                A="$(pkg-config --libs-only-l "$item")"
                B="$(pkg-config --libs-only-other "$item")"
                item="$A $B"
        esac

        XCPKG_TARGET_LDFLAGS="$XCPKG_TARGET_LDFLAGS $item"
    done

    [ -n "$XCPKG_TARGET_LDFLAGS" ] && export XCPKG_TARGET_LDFLAGS

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] ; then
        # https://cmake.org/cmake/help/latest/manual/cmake-env-variables.7.html#manual:cmake-env-variables(7)

        unset CMAKE_PREFIX_PATH
        unset CMAKE_APPLE_SILICON_PROCESSOR
        unset CMAKE_BUILD_PARALLEL_LEVEL
        unset CMAKE_BUILD_TYPE
        unset CMAKE_CONFIGURATION_TYPES
        unset CMAKE_CONFIG_TYPE
        unset CMAKE_EXPORT_COMPILE_COMMANDS
        unset CMAKE_GENERATOR
        unset CMAKE_GENERATOR_INSTANCE
        unset CMAKE_GENERATOR_PLATFORM
        unset CMAKE_GENERATOR_TOOLSET
        unset CMAKE_INSTALL_MODE
        unset CMAKE_C_COMPILER_LAUNCHER
        unset CMAKE_C_LINKER_LAUNCHER
        unset CMAKE_CXX_COMPILER_LAUNCHER
        unset CMAKE_CXX_LINKER_LAUNCHER
        unset CMAKE_MSVCIDE_RUN_PATH
        unset CMAKE_NO_VERBOSE
        unset CMAKE_OSX_ARCHITECTURES
        unset CMAKE_TOOLCHAIN_FILE
        unset DESTDIR
        unset CTEST_INTERACTIVE_DEBUG_MODE
        unset CTEST_OUTPUT_ON_FAILURE
        unset CTEST_PARALLEL_LEVEL
        unset CTEST_PROGRESS_OUTPUT
        unset CTEST_USE_LAUNCHERS_DEFAULT
        unset DASHBOARD_TEST_FROM_CTEST

        # https://cmake.org/cmake/help/latest/envvar/CMAKE_BUILD_PARALLEL_LEVEL.html
        export CMAKE_BUILD_PARALLEL_LEVEL="$BUILD_NJOBS"

        # https://cmake.org/cmake/help/latest/envvar/CMAKE_GENERATOR.html
        if [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] ; then
            export CMAKE_GENERATOR='Ninja'
        else
            export CMAKE_GENERATOR='Unix Makefiles'
        fi

        # https://cmake.org/cmake/help/latest/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.html
        if [ "$EXPORT_COMPILE_COMMANDS_JSON" = 1 ] ; then
            export CMAKE_EXPORT_COMPILE_COMMANDS=ON
        else
            export CMAKE_EXPORT_COMPILE_COMMANDS=OFF
        fi

        case $PROFILE in
            debug)   CMAKE_BUILD_TYPE=Debug   ;;
            release) CMAKE_BUILD_TYPE=Release ;;
        esac

        if [ "$VERBOSE_CMAKE" = 1 ] ; then
            CMAKE_VERBOSE_MAKEFILE=ON
            CMAKE_COLOR_MAKEFILE=ON
            CMAKE_INSTALL_MESSAGE=ALWAYS
        else
            CMAKE_VERBOSE_MAKEFILE=OFF
            CMAKE_COLOR_MAKEFILE=OFF
            CMAKE_INSTALL_MESSAGE=ALWAYS
        fi

        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_DEBUG_MODE.html
        if [ "$DEBUG_CMAKE" = 1 ] ; then
            CMAKE_FIND_DEBUG_MODE=ON
        else
            CMAKE_FIND_DEBUG_MODE=OFF
        fi

        # https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html
        # https://cmake.org/cmake/help/latest/variable/CMAKE_IGNORE_PATH.html
        #
        # https://cmake.org/cmake/help/latest/variable/CMAKE_MODULE_PATH.html
        # https://cmake.org/cmake/help/latest/variable/CMAKE_INCLUDE_PATH.html
        # https://cmake.org/cmake/help/latest/variable/CMAKE_LIBRARY_PATH.html
        # https://cmake.org/cmake/help/latest/variable/CMAKE_PROGRAM_PATH.html
        #
        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH.html
        #
        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH_MODE_PACKAGE.html
        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH_MODE_INCLUDE.html
        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH_MODE_LIBRARY.html
        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_ROOT_PATH_MODE_PROGRAM.html

        CMAKE_FIND_ROOT_PATH="$PACKAGE_WORKING_DIR"

        for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS
        do
            if [ -z "$CMAKE_FIND_ROOT_PATH" ] ; then
                CMAKE_FIND_ROOT_PATH="$DEPENDENT_PACKAGE_INSTALL_DIR"
            else
                CMAKE_FIND_ROOT_PATH="$CMAKE_FIND_ROOT_PATH;$DEPENDENT_PACKAGE_INSTALL_DIR"
            fi
        done
    fi

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] ; then
        # https://docs.rs/backtrace/latest/backtrace/
        export RUST_BACKTRACE=1

        #################################################################

        # https://doc.rust-lang.org/cargo/commands/cargo-rustc.html
        # https://doc.rust-lang.org/rustc/codegen-options/index.html#link-arg
        export RUSTFLAGS="-Clinker=$CC -L native=$PACKAGE_INSTALLING_LIB_DIR"

        for LDFLAG in $LDFLAGS
        do
            RUSTFLAGS="$RUSTFLAGS -Clink-arg=$LDFLAG"
        done

        #################################################################

        # RUST_TARGET environment variable is not defined by Rust, but it is widely used by lots of third-party projects.

        case $TARGET_PLATFORM_NAME/$TARGET_PLATFORM_ARCH in
            MacOSX/x86_64)
                export RUST_TARGET='x86_64-apple-darwin'
                ;;
            *Simulator/x86_64)
                export RUST_TARGET='x86_64-apple-darwin'
                ;;
            MacOSX/arm64)
                export RUST_TARGET='aarch64-apple-darwin'
                ;;
            *Simulator/arm64)
                export RUST_TARGET='aarch64-apple-ios-sim'
                ;;
            */arm64*)
                export RUST_TARGET='aarch64-apple-ios'
                ;;
            *)  export RUST_TARGET="$TARGET_PLATFORM_ARCH-apple-ios"
        esac

        #################################################################

        RUST_TARGET_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$RUST_TARGET" | tr a-z A-Z | tr - _)"

        # https://doc.rust-lang.org/cargo/reference/config.html#environment-variables
        # https://doc.rust-lang.org/cargo/reference/environment-variables.html
        # export "CARGO_TARGET_${RUST_TARGET_UPPERCASE_UNDERSCORE}_AR"="$AR"
        # export "CARGO_TARGET_${RUST_TARGET_UPPERCASE_UNDERSCORE}_LINKER"="$CC"

        export CARGO_BUILD_TARGET="$RUST_TARGET"

        export CARGO_BUILD_TARGET_DIR='target'

        export CARGO_BUILD_JOBS="$BUILD_NJOBS"

        #################################################################

        # https://libraries.io/cargo/cc
        # https://crates.io/crates/cc
        # https://docs.rs/cc/latest/cc/
        # https://github.com/alexcrichton/cc-rs

        if [ "$CROSS_COMPILING" = 1 ] ; then
            export HOST_CC="$CC_FOR_BUILD"
            export HOST_CFLAGS="$CFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD"

            export HOST_CXX="$CXX_FOR_BUILD"
            export HOST_CXXFLAGS="$CXXFLAGS_FOR_BUILD $CPPFLAGS_FOR_BUILD"

            export HOST_AR="$AR"
        else
            export HOST_CC="$CC"
            export HOST_CFLAGS="$CFLAGS $CPPFLAGS"

            export HOST_CXX="$CXX"
            export HOST_CXXFLAGS="$CXXFLAGS $CPPFLAGS"

            export HOST_AR="$AR"
        fi

        export TARGET_CC="$CC"
        export TARGET_CFLAGS="$CFLAGS $CPPFLAGS"

        export TARGET_CXX="$CXX"
        export TARGET_CXXFLAGS="$CXXFLAGS $CPPFLAGS"

        export TARGET_AR="$AR"

        #################################################################

        # https://libraries.io/cargo/pkg-config
        # https://crates.io/crates/pkg-config
        # https://docs.rs/pkg-config/latest/pkg_config/
        # https://github.com/rust-lang/pkg-config-rs
        export TARGET_PKG_CONFIG_ALLOW_CROSS=1

        #################################################################

        # https://libraries.io/cargo/cmake
        # https://crates.io/crates/cmake
        # https://docs.rs/cmake/latest/cmake/
        # https://github.com/alexcrichton/cmake-rs
        # this variable is not motioned in their document. you must read the source code of cmake-rs crate.
        export TARGET_CMAKE_TOOLCHAIN_FILE="$PACKAGE_WORKING_DIR/toolchain.cmake"

        #################################################################

        for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
        do
            case $DEPENDENT_PACKAGE_NAME in
                openssl@1.1)
                    # https://docs.rs/openssl/latest/openssl/
                    export OPENSSL_DIR="$openssl_1_1_INSTALL_DIR"

                    if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/sfackler/rust-openssl/blob/master/openssl-sys/build/main.rs
                        export OPENSSL_STATIC=1
                        export OPENSSL_NO_VENDOR=1
                    fi
                    ;;
                openssl-dev)
                    # https://docs.rs/openssl/latest/openssl/
                    export OPENSSL_DIR="$openssl_dev_INSTALL_DIR"

                    if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/sfackler/rust-openssl/blob/master/openssl-sys/build/main.rs
                        export OPENSSL_STATIC=1
                        export OPENSSL_NO_VENDOR=1
                    fi
                    ;;
                libssh2)
                    if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/alexcrichton/ssh2-rs/blob/master/libssh2-sys/build.rs
                        export LIBSSH2_SYS_USE_PKG_CONFIG=1
                    fi
                    ;;
                libgit2)
                    if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/rust-lang/git2-rs/blob/master/libgit2-sys/build.rs
                        export LIBGIT2_NO_VENDOR=1
                        export LIBGIT2_SYS_USE_PKG_CONFIG=1
                    fi
                    ;;
                libz|zlib)
                    if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
                        # https://github.com/rust-lang/libz-sys/blob/main/build.rs
                        export LIBZ_SYS_STATIC=1
                    fi
                    ;;
            esac
        done
    fi

    #########################################################################################

    if [ "$PACKAGE_USE_BSYSTEM_GO" = 1 ] ; then
        # https://golang.org/doc/install/source#environment

        export CGO_ENABLED=0
        export CGO_CFLAGS="$CFLAGS"
        export CGO_CXXFLAGS="$CXXFLAGS"
        export CGO_CPPFLAGS="$CPPFLAGS"
        export CGO_LDFLAGS="$LDFLAGS"

        export GO111MODULE='auto'

        export GOOS='darwin'

        case $TARGET_PLATFORM_ARCH in
            armv7*)  export GOARCH=arm   ;;
            arm64*)  export GOARCH=arm64 ;;
            aarch64) export GOARCH=arm64 ;;
            i386)    export GOARCH=386   ;;
            i686)    export GOARCH=386   ;;
            x86_64)  export GOARCH=amd64 ;;
        esac
    fi

    #########################################################################################

    [ "$CCACHE_ENABLED" = 1 ] && {
        step "setup ccache"

        run ln -sf "$CCACHE" "$PACKAGE_INSTALLING_BIN_DIR/${CC##*/}"
        run ln -sf "$CCACHE" "$PACKAGE_INSTALLING_BIN_DIR/${CXX##*/}"

        "$CCACHE" -s > "$PACKAGE_WORKING_DIR/ccache-s.txt"
    }

    #########################################################################################

    if [ -n "$RECURSIVE_DEPENDENT_PACKAGE_NAMES" ] ; then
        if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
            step "copy dependent libraries to linker first search dir"

            for DEPENDENT_PACKAGE_INSTALL_DIR in $RECURSIVE_DEPENDENT_PACKAGE_INSTALL_DIRS
            do
                DEPENDENT_PACKAGE_LIBRARY_DIR="$DEPENDENT_PACKAGE_INSTALL_DIR/lib"

                if [  -d "$DEPENDENT_PACKAGE_LIBRARY_DIR" ] ; then
                    find "$DEPENDENT_PACKAGE_LIBRARY_DIR" -maxdepth 1 -mindepth 1 -name 'lib*.a' -exec cp -L -v '{}' "$PACKAGE_WORKING_DIR/lib/" \;
                fi
            done
        fi
    fi

    #########################################################################################

    step "dopatch for target"

    if [ "$PWD" != "$PACKAGE_BSCRIPT_DIR" ] ; then
        run     cd "$PACKAGE_BSCRIPT_DIR"
    fi

    if [ -f "$PACKAGE_INSTALLING_FIX_DIR/index" ] ; then
        for LINE in $(cat "$PACKAGE_INSTALLING_FIX_DIR/index")
        do
            FILE="$(printf '%s\n' "$LINE" | cut -d '|' -f1)"
            OPTS="$(printf '%s\n' "$LINE" | cut -d '|' -f2)"
            [ -z "$OPTS" ] && OPTS='-p1'
            run "patch $OPTS < $PACKAGE_INSTALLING_FIX_DIR/$FILE"
        done
    fi

    [ -n "$PACKAGE_DOPATCH" ] && {
        eval "
dopatch() {
$PACKAGE_DOPATCH
}"
        dopatch
    }

    #########################################################################################

    if [ "$PWD" != "$PACKAGE_BSCRIPT_DIR" ] ; then
        run     cd "$PACKAGE_BSCRIPT_DIR"
    fi

    #########################################################################################

    # https://github.com/golang/go/issues/65568
    if [ -f go.mod ] ; then
        gsed -i 's|^go 1.22$|go 1.22.0|' go.mod
    fi

    #########################################################################################

    case $PACKAGE_BSYSTEM_MASTER in
        autogen)
            if [ -f configure ] ; then
                CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP="$(stat --format=%Y configure)"

                if [ -z "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" ] ; then
                    run NOCONFIGURE=yes ./autogen.sh
                elif [ "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" -lt "$TIMESTAMP_UNIX" ] ; then
                    run NOCONFIGURE=yes ./autogen.sh
                fi
            else
                run NOCONFIGURE=yes ./autogen.sh
            fi
            ;;
        autotools)
            if [ -f configure ] ; then
                CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP="$(stat --format=%Y configure)"

                if [ -z "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" ] ; then
                    run autoreconf -ivf
                elif [ "$CONFIGURE_FILE_LAST_MODIFIED_TIMESTAMP" -lt "$TIMESTAMP_UNIX" ] ; then
                    run autoreconf -ivf
                fi
            else
                run autoreconf -ivf
            fi
            ;;
    esac

    #########################################################################################

    {
        [ "$PACKAGE_USE_BSYSTEM_AUTOGENSH" = 1 ] ||
        [ "$PACKAGE_USE_BSYSTEM_AUTOTOOLS" = 1 ] ||
        [ "$PACKAGE_USE_BSYSTEM_CONFIGURE" = 1 ]
    } && {
        step "update config.{sub,guess}"
        __update_config_sub_guess
    }

    #########################################################################################

    [ -n "$PACKAGE_PREPARE" ] && {
        step "prepare for target"

        if [ "$PWD" != "$PACKAGE_BSCRIPT_DIR" ] ; then
            run     cd "$PACKAGE_BSCRIPT_DIR"
        fi

        eval "
prepare() {
$PACKAGE_PREPARE
}"
        prepare
    }

    #########################################################################################

    step "install for target"

    if [ "$PACKAGE_BINBSTD" = 1 ] ; then
        run cd "$PACKAGE_BSCRIPT_DIR"
    else
        run cd "$PACKAGE_BCACHED_DIR"
    fi

    if [        -d "$PACKAGE_INSTALL_DIR" ] ; then
        run rm -rf "$PACKAGE_INSTALL_DIR"
    fi

    [ "$DUMP_ENV" = 1 ] && {
        run export -p
        printf '\n'
    }

    eval "
dobuild() {
$PACKAGE_DOBUILD
}"

    dobuild

    #########################################################################################

    [   -d "$PACKAGE_INSTALL_DIR" ] || abort 1 "nothing was installed."

    step "change to the installed directory"
    run cd "$PACKAGE_INSTALL_DIR"

    [ -z "$(ls)" ]                  && abort 1 "nothing was installed."

    #########################################################################################

    [ -n "$PACKAGE_DOEXTRA" ] && {
        step "doextra"

        eval "
doextra() {
$PACKAGE_DOEXTRA
}"
        doextra
    }

    #########################################################################################

    __tweak_pc_files

    #########################################################################################

    [ -n "$PACKAGE_DOTWEAK" ] && {
        step "dotweak"

        cd "$PACKAGE_INSTALL_DIR"

        eval "
dotweak() {
$PACKAGE_DOTWEAK
}"
        dotweak
    }

    #########################################################################################

    [ "$PACKAGE_USE_BSYSTEM_CARGO" = 1 ] && {
        run rm -f .crates.toml
        run rm -f .crates2.json
    }

    #########################################################################################

    run cd "$PACKAGE_INSTALL_DIR"

    if [ -d lib ] ; then
        # https://www.linuxfromscratch.org/blfs/view/stable-systemd/introduction/la-files.html
        # remove Libtool Archive (.la) files
        find -L lib -maxdepth 1 -mindepth 1 -type f -name '*.la' -exec rm -v {} +
    fi

    #########################################################################################

    step "generate MANIFEST.txt"
    run install -d .xcpkg/dependencies/lib/
    find -not -path . -a -not -path ./.xcpkg -a -not -path './.xcpkg/*' -printf '%y|%P\n' > .xcpkg/MANIFEST.txt

    #########################################################################################

    step "docheck"

    unset FILES_NEED_TO_BE_SET_RPATH

    __check_mach_o_files

    [ -n "$FILES_NEED_TO_BE_SET_RPATH" ] && {
        step "set rpath for executables"

        KVs="$(printf '%s\n' "$FILES_NEED_TO_BE_SET_RPATH" | sort | uniq)"

        for KV in $KVs
        do
            K="${KV%|*}"
            V="${KV#*|}"

            [ "$V" = 1 ] && V='.xcpkg/dependencies/lib'

            RELATIVE_PATH="$(realpath -m --relative-to="${K%/*}" "$V")"

            run install_name_tool -add_rpath "@executable_path/$RELATIVE_PATH" "$K" || true
        done
    }

    #########################################################################################

    run rmdir --ignore-fail-on-non-empty -p .xcpkg/dependencies/lib/

    run cd .xcpkg

    #########################################################################################

    for item in 'FAQ*' 'TODO*' 'NEWS*' 'THANKS*' 'README*' 'COPYING*' 'LICENSE*' 'AUTHORS*' 'CHANGES*' 'CHANGELOG*' 'CONTRIBUTORS*' 'CONTRIBUTING*'
    do
        find -L "$PACKAGE_INSTALLING_SRC_DIR" -mindepth 1 -maxdepth 1 -type f -iname "$item" -exec cp -L {} . \;
    done

    #########################################################################################

    [ -n "$PACKAGE_DEP_PKG" ] && {
        step "install dependency graph files"

        run mv "$PACKAGE_WORKING_DIR/dependencies.*" .

        step "install dependency formulas"

        install -d dependencies/

        for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
        do
            cp "$SESSION_DIR/$DEPENDENT_PACKAGE_NAME.yml" dependencies/
        done
    }

    #########################################################################################

    for dir in "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR"
    do
        if [ -f "$dir/config.log" ] ; then
            mv  "$dir/config.log" .
        fi
        if [ -f "$dir/compile_commands.json" ] ; then
            mv  "$dir/compile_commands.json" .
        fi
    done

    #########################################################################################

    step "generate RECEIPT.yml"

    cp "$PACKAGE_FORMULA_FILEPATH" RECEIPT.yml

    gsed -i '/^#src-url: dir:/d' RECEIPT.yml

    gsed -i "1i pkgname: $PACKAGE_NAME" RECEIPT.yml

    grep -q '^pkgtype: ' RECEIPT.yml || gsed -i "/^pkgname:/a pkgtype: $PACKAGE_PKGTYPE" RECEIPT.yml
    grep -q '^version: ' RECEIPT.yml || gsed -i "/^pkgtype:/a version: $PACKAGE_VERSION" RECEIPT.yml
    grep -q '^web-url: ' RECEIPT.yml || gsed -i "/^summary:/a web-url: $PACKAGE_GIT_URL" RECEIPT.yml
    grep -q '^git-url: ' RECEIPT.yml || gsed -i "/^web-url:/a git-url: $PACKAGE_GIT_URL" RECEIPT.yml
    grep -q '^bsystem: ' RECEIPT.yml || gsed -i "/^install:/i bsystem: $PACKAGE_BSYSTEM" RECEIPT.yml
    grep -q '^binbstd: ' RECEIPT.yml || gsed -i "/^bsystem:/a binbstd: $PACKAGE_BINBSTD" RECEIPT.yml

    [ -n "$PACKAGE_GIT_SHA" ] && {
        grep -q '^git-sha: ' RECEIPT.yml || {
            gsed -i "/^git-url:/a git-sha: $PACKAGE_GIT_SHA" RECEIPT.yml
        }

        grep -q '^git-sha: ' RECEIPT.yml || {
            gsed -i "3i git-sha: $PACKAGE_GIT_SHA" RECEIPT.yml
        }
    }

    [ -n "$PACKAGE_DEP_UPP" ] && {
        if grep -q '^dep-upp: ' RECEIPT.yml ; then
            gsed -i "/^dep-upp: /c dep-upp: $PACKAGE_DEP_UPP" RECEIPT.yml
        else
            gsed -i "/^bsystem: /i dep-upp: $PACKAGE_DEP_UPP" RECEIPT.yml
        fi
    }

    cat >> RECEIPT.yml <<EOF
profile: $PROFILE
builtfor: $TARGET_PLATFORM_SPEC
builtby: xcpkg-$XCPKG_VERSION
builtat: $TIMESTAMP_UNIX
builton:
    os-arch: $NATIVE_PLATFORM_ARCH
    os-kind: $NATIVE_PLATFORM_KIND
    os-type: $NATIVE_PLATFORM_TYPE
    os-code: $NATIVE_PLATFORM_CODE
    os-name: $NATIVE_PLATFORM_NAME
    os-vers: $NATIVE_PLATFORM_VERS
    os-ncpu: $NATIVE_PLATFORM_NCPU
    os-euid: $NATIVE_PLATFORM_EUID
    os-egid: $NATIVE_PLATFORM_EGID
EOF

    #########################################################################################

    step "generate index"
    run cd "$XCPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC"
    run ln -s -f -T "$PACKAGE_INSTALL_SHA" "$PACKAGE_NAME"

    #########################################################################################

    step "show installed files in tree-like format"
    run tree --dirsfirst -a "$PACKAGE_INSTALL_DIR"

    #########################################################################################

    [ "$ENABLE_CCACHE" = 1 ] && {
        step "show ccache statistics summary"
        note "Before Build:"
        run  cat "$PACKAGE_WORKING_DIR/ccache-s.txt"
        note "After  Build:"
        run  ccache -s
    }

    [ "$KEEP_SESSION_DIR" != 1 ] && {
        step "delete the working directory"
        run rm -rf "$PACKAGE_WORKING_DIR"
    }

    #########################################################################################

    printf '\n%b\n' "${COLOR_PURPLE}✅️  ${COLOR_OFF}${COLOR_GREEN}${1} was successfully installed.${COLOR_OFF}${COLOR_PURPLE}${COLOR_OFF}"

    if [ -n "$PACKAGE_CAVEATS" ] ; then
        printf '\n%b\n' "${COLOR_YELLOW}⚠️  Caveats:${COLOR_OFF}\n\n$PACKAGE_CAVEATS" >&2
    fi
}

__check_mach_o_files() {
    while read -r LINE
    do
        FILETYPE="${LINE%%|*}"
        FILEPATH="${LINE##*|}"

        [ "$FILETYPE" = f ] || continue
        [ -f "$FILEPATH" ]  || continue

        FILE_HEADER_ACTUAL="$(hexdump -n 16 -v -e '1/1 "%02X" ""' "$FILEPATH")"

        unset LIBRARY
        unset EXECUTABLE

        # https://github.com/aidansteele/osx-abi-macho-file-format-reference
        case $FILE_HEADER_ACTUAL in
            CFFAEDFE0C0000010000000002000000)
                # arm64 executable
                EXECUTABLE=1
                ;;
            CFFAEDFE0C0000010000000006000000)
                # arm64 shared library
                LIBRARY=1
                ;;
            CFFAEDFE0C0000010000000008000000)
                # arm64 bundle library
                LIBRARY=1
                ;;
            CFFAEDFE070000010300000002000000)
                # x86_64 executable
                EXECUTABLE=1
                ;;
            CFFAEDFE070000010300000006000000)
                # x86_64 shared library
                LIBRARY=1
                ;;
            CFFAEDFE070000010300000008000000)
                # x86_64 bundle library
                LIBRARY=1
                ;;
            *)  #echo "$FILE_HEADER_ACTUAL:$FILEPATH"
                continue
        esac

        #######################################################################

        DYLIB_ID=$(otool -l "$FILEPATH" | grep LC_ID_DYLIB -A2 | grep name | sed 's|^[[:space:]]*||' | cut -d ' ' -f2)

        RUNPATHs=$(otool -l "$FILEPATH" | grep LC_RPATH    -A2 | grep path | sed 's|^[[:space:]]*||' | cut -d ' ' -f2)

        #######################################################################

        if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
            cat <<EOF
FILEPATH = $FILEPATH
DYLIB_ID = $DYLIB_ID
RUNPATHs = $RUNPATHs
EOF
        fi

        #######################################################################

        case $DYLIB_ID in
            '') ;;
            @rpath/*)
                ;;
            @loader_path/*)
                ;;
            @executable_path/*)
                ;;
            @*) abort 1 "unexpected LC_ID_DYLIB($DYLIB_ID) in $FILEPATH"
                ;;
            *)  run install_name_tool -id "@rpath/${DYLIB_ID##*/}" "$FILEPATH"
        esac

        #######################################################################

        for RPATH in $RUNPATHs
        do
            case $RPATH in
                @loader_path)
                    ;;
                @loader_path/*)
                    ;;
                @executable_path)
                    ;;
                @executable_path/*)
                    ;;
                /usr/lib/*)
                    ;;
                /System/Library/Frameworks/*)
                    ;;
                /*) run install_name_tool -delete_rpath "$RPATH" "$FILEPATH"
            esac
        done

        #######################################################################

        if [ "$LIBRARY" = 1 ] ; then
            run install_name_tool -add_rpath '@loader_path' "$FILEPATH" || true
        fi

        #######################################################################

        __check_needed_dylibs "$FILEPATH" "$EXECUTABLE"
    done < .xcpkg/MANIFEST.txt
}

# __find_needed_shared_library <NEEDED_SHARED_LIBRARY_FILENAME>
  __find_needed_shared_library() {
    unset NEEDED_SHARED_LIBRARY_FILEPATH

    if [ -d lib ] ; then
        NEEDED_SHARED_LIBRARY_FILEPATH="lib/$1"

        [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] || {
            unset NEEDED_SHARED_LIBRARY_FILEPATH
            NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L lib -type f -name "$1" -print -quit)"
        }
    fi

    if [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
        return 0
    fi

    for DEPENDENT_PACKAGE_NAME in $RECURSIVE_DEPENDENT_PACKAGE_NAMES
    do
        NEEDED_SHARED_LIBRARY_ROOT_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$TARGET_PLATFORM_SPEC/$DEPENDENT_PACKAGE_NAME/lib"

        [ -d "$NEEDED_SHARED_LIBRARY_ROOT_DIR" ] || continue

        NEEDED_SHARED_LIBRARY_FILEPATH="$NEEDED_SHARED_LIBRARY_ROOT_DIR/$1"

        [ -f "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && break

        NEEDED_SHARED_LIBRARY_FILEPATH="$(find -L "$NEEDED_SHARED_LIBRARY_ROOT_DIR" -type f -name "$1" -print -quit)"

        [ -n "$NEEDED_SHARED_LIBRARY_FILEPATH" ] && break
    done

    return 0
}

# __check_needed_dylibs <MACH-O-FILE-PATH> <IS-EXECUTABLE>
  __check_needed_dylibs() {
    X="$(printf '%s\n' "$1" | tr / _)"
    Y="$PACKAGE_WORKING_DIR/map/$X"

    if [ -f "$Y" ] ; then
        return 0
    else
        touch "$Y"
    fi

    NEEDEDs=$(otool -l "$1" | grep LC_LOAD_DYLIB -A2 | grep name | sed 's|^[[:space:]]*||' | cut -d ' ' -f2)

    if [ -z "$NEEDEDs" ] ; then
        abort 1 "no needed shared libraries set for $1"
    fi

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_VERBOSE" ] ; then
        cat <<EOF
FILEPATH = $1
NEEDEDs  = $NEEDEDs
EOF
    fi

    for NEEDED in $NEEDEDs
    do
        case $NEEDED in
            /usr/lib/lib*.dylib)
                ;;
            /usr/lib/swift/lib*.dylib)
                ;;
            /System/Library/Frameworks/*)
                ;;
            /System/Library/PrivateFrameworks/*)
                ;;
            $PACKAGE_INSTALL_DIR/*)
                NEEDED_SHARED_LIBRARY_FILENAME="${NEEDED##*/}"

                run install_name_tool -change "$NEEDED" "@rpath/$NEEDED_SHARED_LIBRARY_FILENAME" "$1"

                NEEDED_SHARED_LIBRARY_DIR="${NEEDED%/*}"

                if [ "$2" = 1 ] ; then
                    RELATIVE_PATH="${NEEDED_SHARED_LIBRARY_DIR#$PACKAGE_INSTALL_DIR/}"
                    FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|$RELATIVE_PATH"
                fi
                ;;
            /*)
                NEEDED_SHARED_LIBRARY_FILENAME="${NEEDED##*/}"

                run install_name_tool -change "$NEEDED" "@rpath/$NEEDED_SHARED_LIBRARY_FILENAME" "$1"

                F=".xcpkg/dependencies/lib/$NEEDED_SHARED_LIBRARY_FILENAME"

                if [ ! -f "$F" ] ; then
                    run cp -L "$NEEDED" "$F"
                fi

                if [ "$2" = 1 ] ; then
                    FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|1"
                fi
                ;;
            lib*.dylib)
                run install_name_tool -change "$NEEDED" "@rpath/$NEEDED" "$1"

                __find_needed_shared_library "$NEEDED"

                if [ -z "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
                    abort 1 "$NEEDED was not found, which is needed by $1"
                fi

                case $NEEDED_SHARED_LIBRARY_FILEPATH in
                    /*)
                        F=".xcpkg/dependencies/lib/$NEEDED"

                        if [ ! -f "$F" ] ; then
                            run cp -L "$NEEDED_SHARED_LIBRARY_FILEPATH" "$F"
                        fi

                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|1"
                        fi
                        ;;
                    *)
                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|${NEEDED_SHARED_LIBRARY_FILEPATH%/*}"
                        fi
                esac

                __check_needed_dylibs "$NEEDED_SHARED_LIBRARY_FILEPATH" 0
                ;;
            @rpath/libclang_rt*)
                ;;
            @rpath/*)
                NEEDED_SHARED_LIBRARY_FILENAME="${NEEDED#*/}"

                __find_needed_shared_library "$NEEDED_SHARED_LIBRARY_FILENAME"

                if [ -z "$NEEDED_SHARED_LIBRARY_FILEPATH" ] ; then
                    abort 1 "$NEEDED was not found, which is needed by $1"
                fi

                case $NEEDED_SHARED_LIBRARY_FILEPATH in
                    /*)
                        F=".xcpkg/dependencies/lib/$NEEDED_SHARED_LIBRARY_FILENAME"

                        if [ ! -f "$F" ] ; then
                            run cp -L "$NEEDED_SHARED_LIBRARY_FILEPATH" "$F"
                        fi

                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|1"
                        fi
                        ;;
                    *)
                        if [ "$2" = 1 ] ; then
                            FILES_NEED_TO_BE_SET_RPATH="$FILES_NEED_TO_BE_SET_RPATH
$1|${NEEDED_SHARED_LIBRARY_FILEPATH%/*}"
                        fi
                esac

                __check_needed_dylibs "$NEEDED_SHARED_LIBRARY_FILEPATH" 0
                ;;
            @loader_path/*)
                ;;
            @executable_path/*)
                ;;
            #*)  abort 1 "unexpected runtime dependency: $NEEDED , which is needed by $1"
        esac
    done
}

__tweak_pc_files() {
    unset PC_FILES

    for item in lib share
    do
        PC_FILES_LIVEDIR="$PACKAGE_INSTALL_DIR/$item/pkgconfig"

        if [ -d        "$PC_FILES_LIVEDIR" ] ; then
            fs="$(find "$PC_FILES_LIVEDIR" -type f -name '*.pc')"

            if [ -n "$fs" ] ; then
                PC_FILES="$PC_FILES $fs"
            fi
        fi
    done

    # https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html

    for pcfile in $PC_FILES
    do
        gsed -i \
            -e "s|$PACKAGE_INSTALL_DIR|\${pcfiledir}/../..|g" \
            -e "s|-I${XCPKG_HOME}[^' ]*||g" \
            -e "s|-L${XCPKG_HOME}[^' ]*||g" \
            -e "s|-R[^' ]*||g" \
            -e "s|-F[^' ]*||g" \
            -e "s|-idirafter[^' ]*||g" \
            -e "s|-isysroot [^' ]*||g" \
            -e "s|-arch [^' ]*||g" \
            -e 's|-flto||g' \
            -e 's|-Wl,--strip-debug||g' \
            -e 's|-Wl,-search_paths_first||g' \
            -e "s|-mmacosx-version-min=[^' ]*||g" \
            -e "s|${XCPKG_HOME}/.*/lib\(.*\)\.dylib|-l\1|g" \
            -e "s|${XCPKG_HOME}/.*/lib\(.*\)\.a|-l\1|g" \
            "$pcfile"

        if grep 'Libs.private:' "$pcfile" > /dev/null ; then
            if grep 'Libs:' "$pcfile" > /dev/null ; then
                LIBS_PRIVATE_CONTENT=$(sed -n '/Libs.private:/p' "$pcfile" | cut -c14-)
                gsed -i -e "/Libs:/s|\$|$LIBS_PRIVATE_CONTENT|" -e '/Libs.private:/d' "$pcfile"
            else
                gsed -i 's|Libs.private:|Libs:|' "$pcfile"
            fi
        fi

        if grep 'Requires.private:' "$pcfile" > /dev/null ; then
            if grep 'Requires:' "$pcfile" > /dev/null ; then
                REQUIRES_PRIVATE_CONTENT=$(sed -n '/Requires.private:/p' "$pcfile" | cut -c18-)
                gsed -i -e "/Requires:/s|\$|$REQUIRES_PRIVATE_CONTENT|" -e '/Requires.private:/d' "$pcfile"
            else
                gsed -i 's|Requires.private:|Requires:|' "$pcfile"
            fi
        fi
    done
}

# install_incs [:sub-dir] <FILE>...
install_incs() {
    unset X

    case $1 in
        :*) X="${1#:}"; shift
    esac

    while [ -n "$1" ]
    do
        install -v -d          "$PACKAGE_INSTALL_DIR/include/$X/"
        install -v -m 644 "$1" "$PACKAGE_INSTALL_DIR/include/$X/"
        shift
    done
}

install_libs() {
    install -v -d "$PACKAGE_INSTALL_DIR/lib"
    for item in "$@"
    do
        case $item in
            *.a) install -v -m 644 "$item" "$PACKAGE_INSTALL_DIR/lib" ;;
            *)   install -v -m 755 "$item" "$PACKAGE_INSTALL_DIR/lib" ;;
        esac
    done
}

writepc() {
    install -v -d "$PACKAGE_INSTALL_DIR/lib/pkgconfig" &&
    cat >         "$PACKAGE_INSTALL_DIR/lib/pkgconfig/$1.pc"
}

install_pcfs() {
    install -v -d          "$PACKAGE_INSTALL_DIR/lib/pkgconfig" &&
    install -v -m 644 "$@" "$PACKAGE_INSTALL_DIR/lib/pkgconfig"
}

install_bins() {
    install -v -d          "$PACKAGE_INSTALL_DIR/bin" &&
    install -v -m 755 "$@" "$PACKAGE_INSTALL_DIR/bin"
}

install_etcs() {
    install -v -d          "$PACKAGE_INSTALL_DIR/etc" &&
    install -v -m 644 "$@" "$PACKAGE_INSTALL_DIR/etc"
}

install_mans() {
    for item in "$@"
    do
        unset NUMBER
        NUMBER=$(echo "$item" | cut -c ${#item}-${#item})
        case $NUMBER in
            [1-8]);;
            *)    abort 1 "$item: not a manpage."
        esac
        install -v -d             "$PACKAGE_INSTALL_DIR/share/man/man$NUMBER" &&
        install -v -m 644 "$item" "$PACKAGE_INSTALL_DIR/share/man/man$NUMBER"
    done
}

# install_completion <fish|bash|zsh> <COMMAND> <FILE-PATH>
  install_completion() {
    case $1 in
        bash)
            install -v -d          "$PACKAGE_INSTALL_DIR/share/bash/completions" &&
            install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/bash/completions/$2"
            ;;
        fish)
            install -v -d          "$PACKAGE_INSTALL_DIR/share/fish/vendor_completions.d" &&
            install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/fish/vendor_completions.d/$2.fish"
            ;;
        zsh)
            install -v -d          "$PACKAGE_INSTALL_DIR/share/zsh/site-functions" &&
            install -v -m 644 "$3" "$PACKAGE_INSTALL_DIR/share/zsh/site-functions/_$2"
            ;;
        *)  abort 1 "install_completion unsupported shell: $1"
    esac
}

# __symlink_installed_files_of_the_given_package <PACKAGE-NAME>
  __symlink_installed_files_of_the_given_package() {
      return 0
    # while read -r item
    # do
    #     X=$(printf '%s\n' "$item" | cut -d '|' -f1)
    #     Y=$(printf '%s\n' "$item" | cut -d '|' -f3)

    #     case $X in
    #         d)  ;;
    #         D)  ;;
    #         *)  case $Y in
    #                 share/info/dir) ;;
    #                 *)  if [ -L "$XCPKG_PACKAGE_SYMLINKED_ROOT/$Y" ] || [ -e "$XCPKG_PACKAGE_SYMLINKED_ROOT/$Y" ] ; then
    #                         abort 1 "$XCPKG_PACKAGE_SYMLINKED_ROOT/$Y already exists."
    #                     # else
    #                     #     echo "$XCPKG_PACKAGE_SYMLINKED_ROOT/$Y"
    #                     fi
    #             esac
    #     esac
    # done < "$PACKAGE_MANIFEST_FILEPATH"

    # ############################################################################

    if [ !      -d "$XCPKG_PACKAGE_SYMLINKED_ROOT/.registry" ] ; then
        install -d "$XCPKG_PACKAGE_SYMLINKED_ROOT/.registry"
    fi

    exec 7> "$XCPKG_PACKAGE_SYMLINKED_ROOT/.registry/$1"

    while read -r item
    do
        X=$(printf '%s\n' "$item" | cut -d '|' -f1)
        Y=$(printf '%s\n' "$item" | cut -d '|' -f3)

        case $X in
            d|D)
                if [ !      -d "$XCPKG_PACKAGE_SYMLINKED_ROOT/$Y" ] ; then
                    install -d "$XCPKG_PACKAGE_SYMLINKED_ROOT/$Y"
                fi
                ;;
            *)  case $Y in
                    share/info/dir) ;;
                    *)  run ln -sfr "\"$XCPKG_PACKAGE_INSTALLED_ROOT/$1/$Y\"" "\"$XCPKG_PACKAGE_SYMLINKED_ROOT/$Y\""
                        printf '%s\n' "$Y" >&7
                esac
        esac
    done < "$PACKAGE_MANIFEST_FILEPATH"

    exec 7>&-
}

# }}}
##############################################################################
# {{{ cabal_v2_install

# https://cabal.readthedocs.io/en/3.14/cabal-project-description-file.html
cabal_v2_install() {
    if [ -z "$BOOTSTRAP_HASKELL_GHC_VERSION" ] ; then
        if [ -f cabal.project ] ; then
            HASKELL_GHC_VERSION="$(gsed -n '/^with-compiler: ghc-/p' cabal.project)"

            if [ -n "$HASKELL_GHC_VERSION" ] ; then
                HASKELL_GHC_VERSION="${HASKELL_GHC_VERSION#'with-compiler: ghc-'}"

                if [ -n "$HASKELL_GHC_VERSION" ] ; then
                    export BOOTSTRAP_HASKELL_GHC_VERSION="$HASKELL_GHC_VERSION"
                fi
            fi
        fi

        if [ -z "$BOOTSTRAP_HASKELL_GHC_VERSION" ] ; then
            export BOOTSTRAP_HASKELL_GHC_VERSION='9.8.2'
        fi
    fi

    export BOOTSTRAP_HASKELL_CABAL_VERSION='3.14.1.1'
    export BOOTSTRAP_HASKELL_NONINTERACTIVE=1
    export BOOTSTRAP_HASKELL_VERBOSE=1
    export BOOTSTRAP_HASKELL_INSTALL_NO_STACK=1

    unset  BOOTSTRAP_HASKELL_INSTALL_HLS
    unset  BOOTSTRAP_HASKELL_CABAL_XDG
    unset  BOOTSTRAP_HASKELL_DOWNLOADER
    unset  BOOTSTRAP_HASKELL_ADJUST_BASHRC
    unset  BOOTSTRAP_HASKELL_MINIMAL

    unset  GHCUP_USE_XDG_DIRS
    unset  GHCUP_BASE_URL

    export GHCUP_INSTALL_BASE_PREFIX="$PACKAGE_WORKING_DIR"

    if [ "$GITHUB_ACTIONS" = true ] ; then
        DEBUG_CABAL=1
    fi

    wfetch 'https://get-ghcup.haskell.org' -o ghcup-installer.sh
    gsed -i '/GHCUP_INSTALL_BASE_PREFIX:=/d'  ghcup-installer.sh
    run sh ghcup-installer.sh

    export LD_LIBRARY_PATH="$libncurses_LIBRARY_DIR:$libgmp_LIBRARY_DIR"

    export PROXIED_CC_ARGS="$PROXIED_CC_ARGS -L$PACKAGE_WORKING_DIR/lib"
    export PROXIED_CXX_ARGS="$PROXIED_CXX_ARGS -L$PACKAGE_WORKING_DIR/lib"

    export PATH="$GHCUP_INSTALL_BASE_PREFIX/.ghcup/bin:$PATH"

    if [ ! -f cabal.project ] ; then
        cat > cabal.project <<EOF
packages: ./*.cabal
EOF
    fi

    cat >> cabal.project <<EOF

package *
    extra-include-dirs: $PACKAGE_WORKING_DIR/include$CABAL_PROJECT_EXTRA_INCLUDE_DIRS
    extra-lib-dirs: $PACKAGE_WORKING_DIR/lib$CABAL_PROJECT_EXTRA_LIBRARY_DIRS

EOF

    CABAL_ARGS="--jobs=$BUILD_NJOBS --max-backjumps=100000 --install-method=copy --installdir=$PACKAGE_INSTALL_DIR/bin"

    if [ "$VERBOSE_CABAL" = 1 ] ; then
        CABAL_ARGS="$CABAL_ARGS -v2"
    fi

    if [ "$DEBUG_CABAL" = 1 ] ; then
        CABAL_ARGS="$CABAL_ARGS -v3"
    fi

    if [ "$ENABLE_STRIP" = 1 ] ; then
        CABAL_ARGS="$CABAL_ARGS --enable-executable-stripping"
    fi

    CABAL=$(command -v cabal) || abort 1 "command not found: cabal"

    run "$CABAL" --version
    run "$CABAL" update
    run "$CABAL" v2-install "$CABAL_ARGS" "$@"
}

# }}}
##############################################################################
# {{{ netsurf_buildsystem

netsurf_buildsystem() {
    gmakew install COMPONENT_TYPE=lib-static NSSHARED="$NATIVE_PACKAGE_INSTALLED_ROOT/netsurf_buildsystem/share/netsurf-buildsystem" PREFIX="$PACKAGE_INSTALL_DIR"
    gmakew install COMPONENT_TYPE=lib-shared NSSHARED="$NATIVE_PACKAGE_INSTALLED_ROOT/netsurf_buildsystem/share/netsurf-buildsystem" PREFIX="$PACKAGE_INSTALL_DIR"
}

# }}}
##############################################################################
# {{{ waf

waf() {
    PYTHON3=$(command -v python3) || abort 1 "command not found: python3"

    run "$PYTHON3" ./waf configure --prefix=$PACKAGE_INSTALL_DIR $@
    run "$PYTHON3" ./waf build
    run "$PYTHON3" ./waf install
}

# }}}
##############################################################################
# {{{ zig

zig() {
    ZIG_BUILD_EXTRA_ARGS="-j$BUILD_NJOBS"

    if [ "$TARGET_PLATFORM_NAME" = MacOSX ] ; then
        # https://zig.guide/build-system/cross-compilation/
        if [ $TARGET_PLATFORM_ARCH = arm64 ] ; then
            ZIG_BUILD_TARGET='aarch64-macos'
        else
            ZIG_BUILD_TARGET=$TARGET_PLATFORM_ARCH-macos
        fi

        ZIG_BUILD_EXTRA_ARGS="$ZIG_BUILD_EXTRA_ARGS -Dtarget=$ZIG_BUILD_TARGET"
    fi

    case $PROFILE in
        release) ZIG_BUILD_EXTRA_ARGS="$ZIG_BUILD_EXTRA_ARGS --release=small" ;;
    esac

    if [ "$LOG_LEVEL" -ge "$LOG_LEVEL_NORMAL" ] ; then
        ZIG_BUILD_EXTRA_ARGS="$ZIG_BUILD_EXTRA_ARGS --verbose"
    fi

    run command zig build $ZIG_BUILD_EXTRA_ARGS --prefix "$PACKAGE_INSTALL_DIR" "$@"
}

# }}}
##############################################################################
# {{{ configure

configure() {
    unset CONFIGURE_ONLY

    if [ "$1" = only ] ; then
        CONFIGURE_ONLY=1
        shift
    fi

    export FORCE_UNSAFE_CONFIGURE=1

    export ac_cv_func_malloc_0_nonnull=yes
    export ac_cv_func_calloc_0_nonnull=yes
    export ac_cv_func_realloc_0_nonnull=yes


    if [ "$BUILD_FOR_NATIVE" = 1 ] ; then
        if run "$PACKAGE_BSCRIPT_DIR"/configure \
            --prefix="$PACKAGE_INSTALL_DIR" \
            "$@" ; then
            printf '\n'
        else
            if [ -f "$PACKAGE_BCACHED_DIR/config.log" ] ; then
                run cat "$PACKAGE_BCACHED_DIR/config.log"
            elif [ -f "$PACKAGE_BSCRIPT_DIR/config.log" ] ; then
                run cat "$PACKAGE_BSCRIPT_DIR/config.log"
            fi
            return 1
        fi
    else
        unset TARGET_TRIPLE

        if [ 'arm64' = "$TARGET_PLATFORM_ARCH" ] ; then
            if [ "$PACKAGE_IOS_IOS" = 1 ] ; then
                TARGET_TRIPLE='aarch64-apple-ios'
            else
                TARGET_TRIPLE='aarch64-apple-darwin'
            fi
        else
            if [ "$PACKAGE_IOS_IOS" = 1 ] ; then
                TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-apple-ios"
            else
                TARGET_TRIPLE="$TARGET_PLATFORM_ARCH-apple-darwin"
            fi
        fi

        CONFIGURE_ARG_ENABLE_NLS=0
        CONFIGURE_ARG_ENABLE_RPATH=0
        CONFIGURE_ARG_ENABLE_LARGEFILE=1

        CONFIGURE_ARG_ENABLE_DEBUG=
        CONFIGURE_ARG_ENABLE_STATIC=
        CONFIGURE_ARG_ENABLE_SHARED=

        for arg in "$@"
        do
            case $arg in
                --enable-nls)      CONFIGURE_ARG_ENABLE_NLS=1 ;;
                --enable-nls=yes)  CONFIGURE_ARG_ENABLE_NLS=1 ;;
                --enable-nls=no)   CONFIGURE_ARG_ENABLE_NLS=0 ;;
                --disable-nls)     CONFIGURE_ARG_ENABLE_NLS=0 ;;

                --enable-rpath)     CONFIGURE_ARG_ENABLE_RPATH=1 ;;
                --enable-rpath=yes) CONFIGURE_ARG_ENABLE_RPATH=1 ;;
                --enable-rpath=no)  CONFIGURE_ARG_ENABLE_RPATH=0 ;;
                --disable-rpath)    CONFIGURE_ARG_ENABLE_RPATH=0 ;;

                --enable-largefile)     CONFIGURE_ARG_ENABLE_LARGEFILE=1 ;;
                --enable-largefile=yes) CONFIGURE_ARG_ENABLE_LARGEFILE=1 ;;
                --enable-largefile=no)  CONFIGURE_ARG_ENABLE_LARGEFILE=0 ;;
                --disable-largefile)    CONFIGURE_ARG_ENABLE_LARGEFILE=0 ;;

                --enable-debug)     CONFIGURE_ARG_ENABLE_DEBUG=1 ;;
                --enable-debug=yes) CONFIGURE_ARG_ENABLE_DEBUG=1 ;;
                --enable-debug=no)  CONFIGURE_ARG_ENABLE_DEBUG=0 ;;
                --disable-debug)    CONFIGURE_ARG_ENABLE_DEBUG=0 ;;

                --enable-static)     CONFIGURE_ARG_ENABLE_STATIC=1 ;;
                --enable-static=yes) CONFIGURE_ARG_ENABLE_STATIC=1 ;;
                --enable-static=no)  CONFIGURE_ARG_ENABLE_STATIC=0 ;;
                --disable-static)    CONFIGURE_ARG_ENABLE_STATIC=0 ;;

                --enable-shared)     CONFIGURE_ARG_ENABLE_SHARED=1 ;;
                --enable-shared=yes) CONFIGURE_ARG_ENABLE_SHARED=1 ;;
                --enable-shared=no)  CONFIGURE_ARG_ENABLE_SHARED=0 ;;
                --disable-shared)    CONFIGURE_ARG_ENABLE_SHARED=0 ;;
            esac
        done

        CONFIGURE_ARGS="--prefix='$PACKAGE_INSTALL_DIR'"

        if [ "$CROSS_COMPILING" = 1 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --host='$TARGET_TRIPLE'"
        fi

        CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-option-checking"

        if [ "$CONFIGURE_ARG_ENABLE_NLS" = 1 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-nls"
        else
            CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-nls"
        fi

        if [ "$CONFIGURE_ARG_ENABLE_RPATH" = 1 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-rpath"
        else
            CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-rpath"
        fi

        if [ "$CONFIGURE_ARG_ENABLE_LARGEFILE" = 1 ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-largefile"
        else
            CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-largefile"
        fi

        if [ -z "$CONFIGURE_ARG_ENABLE_DEBUG" ] ; then
            case $PROFILE in
                debug)   CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-debug"  ;;
                release) CONFIGURE_ARGS="$CONFIGURE_ARGS --disable-debug" ;;
            esac
        fi

        if [ -z "$CONFIGURE_ARG_ENABLE_STATIC" ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-static"
        fi

        if [ -z "$CONFIGURE_ARG_ENABLE_SHARED" ] ; then
            CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-shared"
        fi

        CONFIGURE_ENVS="$CONFIGURE_ENVS --with-pic
            CC='$CC'
            CFLAGS='$CFLAGS'
            CXX='$CXX'
            CXXFLAGS='$CXXFLAGS'
            CPP='$CPP'
            CPPFLAGS='$CPPFLAGS'
            LDFLAGS='$LDFLAGS'
            AR='$AR'
            RANLIB='$RANLIB'
            PKG_CONFIG='$PKG_CONFIG'
            PKG_CONFIG_PATH='$PKG_CONFIG_PATH'
            PKG_CONFIG_LIBDIR='$PKG_CONFIG_LIBDIR'
            CC_FOR_BUILD='$CC_FOR_BUILD'"

        CONFIGURE="$PACKAGE_BSCRIPT_DIR/configure"

        if [ "$CROSS_COMPILING" = 1 ] ; then
            gsed -i 's/cross_compiling=no/cross_compiling=yes/g' "$CONFIGURE"
        fi

        if run $CONFIGURE $CONFIGURE_ARGS $@ $CONFIGURE_ENVS ; then
            echo
        else
            # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables
            if [ "$GITHUB_ACTIONS" = true ] ; then
                if [ -f "$PACKAGE_BCACHED_DIR/config.log" ] ; then
                    run cat "$PACKAGE_BCACHED_DIR/config.log"
                elif [ -f "$PACKAGE_BSCRIPT_DIR/config.log" ] ; then
                    run cat "$PACKAGE_BSCRIPT_DIR/config.log"
                fi
            fi
            return 1
        fi
    fi

    if [ "$VERBOSE_GMAKE" = 1 ] ; then
        for Makefile in $(find "$PACKAGE_BSCRIPT_DIR" -name Makefile)
        do
            gsed -i 's|\t@|\t|g'     "$Makefile"
            gsed -i 's|@echo|echo|g' "$Makefile"
        done
        unset Makefile
    fi

    if [ "$CONFIGURE_ONLY" != 1 ] ; then
        gmakew clean
        gmakew
        gmakew install
    fi
}

# }}}
##############################################################################
# {{{ gmakew

gmakew() {
    GMAKE_ARGS="-w -j$BUILD_NJOBS"

    if [ "$DEBUG_GMAKE" = 1 ] ; then
        GMAKE_ARGS="$GMAKE_ARGS --debug"
    fi

    if [ "$VERBOSE_GMAKE" = 1 ] ; then
        GMAKE_ARGS="$GMAKE_ARGS V=1"
    fi

    run "$GMAKE" "$GMAKE_ARGS" "$@"
}

# }}}
##############################################################################
# {{{ ninjaw

ninjaw() {
    if [ "$VERBOSE_NINJA" = 1 ] ; then
        run "$NINJA" -j "$BUILD_NJOBS" -v "$@"
    else
        run "$NINJA" -j "$BUILD_NJOBS"    "$@"
    fi
}

# }}}
##############################################################################
# {{{ cmakew

# cmakew [2] [--targets=<comma-separated list>] [--components=<comma-separated list>] [CMAKE-OPTIONS]
cmakew() {
    unset CMAKE_EXTRA_ARGS
    unset CMAKE_BUILD_TARGETS
    unset CMAKE_INSTALL_COMPONENTS
    unset CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY

    if [ "$1" = 2 ] ; then
        CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY=1
        shift
    fi

    while [ -n "$1" ]
    do
        case $1 in
            -S) shift; PACKAGE_BSCRIPT_DIR="$1" ;;
            -B) shift; PACKAGE_BCACHED_DIR="$1" ;;
            --targets=*)
                TARGETS="${1#*=}"

                export IFS=','

                for item in $TARGETS
                do
                    CMAKE_BUILD_TARGETS="$CMAKE_BUILD_TARGETS $item"
                done

                unset IFS
                ;;
            --components=*)
                COMPONENTS="${1#*=}"

                export IFS=','

                for item in $COMPONENTS
                do
                    CMAKE_INSTALL_COMPONENTS="$CMAKE_INSTALL_COMPONENTS $item"
                done

                unset IFS
                ;;
            *)  CMAKE_EXTRA_ARGS="$CMAKE_EXTRA_ARGS $1"
        esac
        shift
    done

    if [ "$CMAKE_BUILD_STATIC_SHARED_LIBRARY_SEPARATEDLY" = 1 ] ; then
        cmakew_internal $CMAKE_EXTRA_ARGS -DBUILD_SHARED_LIBS=OFF
        cmakew_internal $CMAKE_EXTRA_ARGS -DBUILD_SHARED_LIBS=ON
    else
        cmakew_internal $CMAKE_EXTRA_ARGS
    fi
}

cmakew_internal() {
    if [ "$BUILD_FOR_NATIVE" = 1 ] ; then
        cmakew_for_native "$@"
    else
        cmakew_for_target "$@"
    fi
}

cmakew_for_native() {
    if [ "$PACKAGE_USE_BSYSTEM_NINJA" = 1 ] ; then
        CMAKE_GENERATOR='Ninja'
    else
        CMAKE_GENERATOR='Unix Makefiles'
    fi

    if [ "$VERBOSE_CMAKE" = 1 ] ; then
        CMAKE_VERBOSE_MAKEFILE=ON
        CMAKE_COLOR_MAKEFILE=ON
    else
        CMAKE_VERBOSE_MAKEFILE=OFF
        CMAKE_COLOR_MAKEFILE=OFF
    fi

    if [ "$DEBUG_CMAKE" = 1 ] ; then
        CMAKE_FIND_DEBUG_MODE=ON
    else
        CMAKE_FIND_DEBUG_MODE=OFF
    fi

    run "$CMAKE" \
        -Wno-dev \
        -G "'$CMAKE_GENERATOR'" \
        -S "$PACKAGE_BSCRIPT_DIR" \
        -B "$PACKAGE_BCACHED_DIR" \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX="$PACKAGE_INSTALL_DIR" \
        -DCMAKE_FIND_DEBUG_MODE="$CMAKE_FIND_DEBUG_MODE" \
        -DCMAKE_VERBOSE_MAKEFILE="$CMAKE_VERBOSE_MAKEFILE" \
        -DCMAKE_COLOR_MAKEFILE="$CMAKE_COLOR_MAKEFILE" \
        -DBUILD_SHARED_LIBS=OFF \
        -DBUILD_TESTING=OFF \
        "$@" &&
    run "$CMAKE" --build   "$PACKAGE_BCACHED_DIR" -- "-j$BUILD_NJOBS" &&
    run "$CMAKE" --install "$PACKAGE_BCACHED_DIR"
}

cmakew_for_target() {
    CMAKE_TOOLCHAIN_FILE="$PACKAGE_WORKING_DIR/toolchain.cmake"

    cat > "$CMAKE_TOOLCHAIN_FILE" <<EOF
set(CMAKE_SYSTEM_VERSION   $TARGET_PLATFORM_VERS)
set(CMAKE_SYSTEM_PROCESSOR $TARGET_PLATFORM_ARCH)
EOF

    if [ "$CROSS_COMPILING" = 1 ] ; then
        # https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-ios-tvos-or-watchos
        case $TARGET_PLATFORM_NAME in
            iPhoneOS|iPhoneSimulator)
                CMAKE_SYSTEM_NAME=iOS
                ;;
            WatchOS|WatchSimulator)
                CMAKE_SYSTEM_NAME=watchOS
                ;;
            AppleTVOS|AppleTVSimulator)
                CMAKE_SYSTEM_NAME=tvOS
                ;;
            *)  CMAKE_SYSTEM_NAME=Darwin
        esac

        cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF
set(CMAKE_SYSTEM_NAME      $CMAKE_SYSTEM_NAME)
EOF
    fi

    cat >> "$CMAKE_TOOLCHAIN_FILE" <<EOF

message(STATUS "CMake command: \${CMAKE_COMMAND}")
message(STATUS "CMake version: \${CMAKE_VERSION}")

message(STATUS "CMAKE_HOST_SYSTEM_NAME: \${CMAKE_HOST_SYSTEM_NAME}")
message(STATUS "     CMAKE_SYSTEM_NAME: \${CMAKE_SYSTEM_NAME}")

if ("\${BUILD_SHARED_LIBS}" STREQUAL "")
    set(BUILD_SHARED_LIBS $BUILD_SHARED_LIBS)
endif()

set(CMAKE_BUILD_TYPE  $CMAKE_BUILD_TYPE)

set(CMAKE_C_COMPILER "$CC")
set(CMAKE_C_FLAGS "$CFLAGS $CPPFLAGS")

set(CMAKE_CXX_COMPILER "$CXX")
set(CMAKE_CXX_FLAGS "$CXXFLAGS $CPPFLAGS")

set(CMAKE_ASM_COMPILER "$CC")
set(CMAKE_ASM_FLAGS "$XCPKG_COMPILER_ARGS")

set(CMAKE_SHARED_LINKER_FLAGS "$LDFLAGS")
set(CMAKE_EXE_LINKER_FLAGS    "$LDFLAGS")

set(CMAKE_AR     "$AR")
set(CMAKE_RANLIB "$RANLIB")

set(CMAKE_LINKER "$LD")

set(CMAKE_NM     "$NM")

set(CMAKE_STRIP  "$STRIP")

set(CMAKE_OSX_SYSROOT "$SYSROOT")

# https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html
set(CMAKE_OSX_ARCHITECTURES "$TARGET_PLATFORM_ARCH" CACHE STRING "")

set(CMAKE_FIND_DEBUG_MODE $CMAKE_FIND_DEBUG_MODE)

set(CMAKE_FIND_ROOT_PATH "$CMAKE_FIND_ROOT_PATH")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# https://stackoverflow.com/questions/36523911/osx-homebrew-cmake-libpng-version-mismatch-issue
# https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_FRAMEWORK.html
set(CMAKE_FIND_FRAMEWORK LAST)

# https://cmake.org/cmake/help/latest/variable/CMAKE_MACOSX_BUNDLE.html
# https://github.com/Kitware/CMake/blob/master/Modules/Platform/Darwin.cmake
if (NOT DEFINED CMAKE_MACOSX_BUNDLE)
    set(CMAKE_MACOSX_BUNDLE OFF)
endif()

set(CMAKE_INSTALL_MESSAGE $CMAKE_INSTALL_MESSAGE)
EOF
    [ "$VERBOSE_CMAKE" = 1 ] && {
        run bat --language=cmake --paging=never --style=numbers,grid "$CMAKE_TOOLCHAIN_FILE"
    }

    unset CMAKE_PROJECT_INCLUDE

    if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        # https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_INCLUDE.html
        CMAKE_PROJECT_INCLUDE="$PACKAGE_WORKING_DIR/project-after.cmake"

        # https://cmake.org/cmake/help/latest/variable/CMAKE_FIND_LIBRARY_SUFFIXES.html
        printf 'set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".dylib")\n' > "$CMAKE_PROJECT_INCLUDE"

        if [ "$VERBOSE_CMAKE" = 1 ] ; then
            run bat --language=cmake --paging=never --style=plain "$CMAKE_PROJECT_INCLUDE"
        fi
    fi

    if [ -f "$PACKAGE_BCACHED_DIR/CMakeCache.txt" ] ; then
        rm  "$PACKAGE_BCACHED_DIR/CMakeCache.txt"
    fi

    BUILD_SHARED_LIBS_IS_SPECIFIED=0

    for OPT in "$@"
    do
        case $OPT in
            -DBUILD_SHARED_LIBS=*) BUILD_SHARED_LIBS_IS_SPECIFIED=1; break
        esac
    done

    if [ -z "$CMAKE_PROJECT_INCLUDE" ] ; then
        CMAKE_CONFIG_OPTIONS_EXTRA=
    else
        CMAKE_CONFIG_OPTIONS_EXTRA="-DCMAKE_PROJECT_INCLUDE='$CMAKE_PROJECT_INCLUDE'"
    fi

    run "$CMAKE" \
        -Wno-dev \
        -S "$PACKAGE_BSCRIPT_DIR" \
        -B "$PACKAGE_BCACHED_DIR" \
        -DBUILD_TESTING=OFF \
        -DCMAKE_INSTALL_PREFIX="$PACKAGE_INSTALL_DIR" \
        -DCMAKE_TOOLCHAIN_FILE="$CMAKE_TOOLCHAIN_FILE" \
        -DCMAKE_VERBOSE_MAKEFILE="$CMAKE_VERBOSE_MAKEFILE" \
        -DCMAKE_COLOR_MAKEFILE="$CMAKE_COLOR_MAKEFILE" \
        "$CMAKE_CONFIG_OPTIONS_EXTRA" "$@"

    if [ -z "$CMAKE_BUILD_TARGETS" ] ; then
        run "$CMAKE" --build   "$PACKAGE_BCACHED_DIR"
    else
        run "$CMAKE" --build   "$PACKAGE_BCACHED_DIR" --target "$CMAKE_BUILD_TARGETS"
    fi

    if [ -z "$CMAKE_INSTALL_COMPONENTS" ] ; then
        run "$CMAKE" --install "$PACKAGE_BCACHED_DIR"
    else
        for component in $CMAKE_INSTALL_COMPONENTS
        do
        run "$CMAKE" --install "$PACKAGE_BCACHED_DIR" --component "$component"
        done
    fi
}

# }}}
##############################################################################
# {{{ xmakew

# run in a subshell
xmakew() {
    export CC="$XCPKG_CC"
    export AS="$XCPKG_CC"
    export LD="$XCPKG_CC"

    XMAKE_CONFIG_OPTIONS="$*"

    XMAKE_CONFIG_OPTION_CLEAN=
    XMAKE_CONFIG_OPTION_MODE=
    XMAKE_CONFIG_OPTION_vD=

    for arg in "$@"
    do
        case $arg in
            -c|--clean)  XMAKE_CONFIG_OPTION_CLEAN='set' ;;
            -m|--mode=*) XMAKE_CONFIG_OPTION_MODE='set'  ;;
            -vD)         XMAKE_CONFIG_OPTION_vD='set' ;;
        esac
    done

    if [ "$DEBUG_XMAKE" = 1 ] ; then
        if [ -z "$XMAKE_CONFIG_OPTION_vD" ]; then
            XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS -vD"
        fi
    else
        if [ "$VERBOSE_XMAKE" = 1 ] ; then
            XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS -v"
        fi
    fi

    if [ -z "$XMAKE_CONFIG_OPTION_CLEAN" ] ; then
        XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --clean"
    fi

    if [ -z "$XMAKE_CONFIG_OPTION_MODE" ] ; then
        XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --mode=$PROFILE"
    fi

    if [ "$BUILD_FOR_NATIVE" = 1 ] ; then
        run $XMAKE config $XMAKE_CONFIG_OPTIONS --project=$PACKAGE_BSCRIPT_DIR --buildir=$PACKAGE_BCACHED_DIR &&
        run $XMAKE --jobs=$BUILD_NJOBS &&
        run $XMAKE install -o "$PACKAGE_INSTALL_DIR"
    else
        unset XMAKE_PLATFORM
        XMAKE_PLATFORM="$(printf '%s\n' "$TARGET_PLATFORM_NAME_LOWER_CASE" | sed 's|simulator|os|')"
        XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --plat=$XMAKE_PLATFORM"

        case $TARGET_PLATFORM_NAME in
            *Simulator) XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --appledev=simulator"
        esac

        XMAKE_CONFIG_OPTIONS="$XMAKE_CONFIG_OPTIONS --arch=$TARGET_PLATFORM_ARCH --buildir=$PACKAGE_BCACHED_DIR"

        run $XMAKE config $XMAKE_CONFIG_OPTIONS &&
        run $XMAKE --jobs=$BUILD_NJOBS &&
        run $XMAKE install -o "$PACKAGE_INSTALL_DIR"
    fi
}

# }}}
##############################################################################
# {{{ mesonw

# https://mesonbuild.com/Cross-compilation.html
# run in a subshell
mesonw() {
    case $TARGET_PLATFORM_ARCH in
        armv7*)
            HOST_MACHINE_CPU_FAMILY='arm'
            HOST_MACHINE_CPU_NAME="$TARGET_PLATFORM_ARCH"
            ;;
        arm64*|aarch64)
            HOST_MACHINE_CPU_FAMILY='aarch64'
            HOST_MACHINE_CPU_NAME='armv8a'
            ;;
        i386|i686)
            HOST_MACHINE_CPU_FAMILY='x86'
            HOST_MACHINE_CPU_NAME="$TARGET_PLATFORM_ARCH"
            ;;
        x86_64)
            HOST_MACHINE_CPU_FAMILY='x86_64'
            HOST_MACHINE_CPU_NAME="$TARGET_PLATFORM_ARCH"
            ;;
    esac

    MESON_CROSS_FILE="$PACKAGE_WORKING_DIR/cross-file"

    cat > "$MESON_CROSS_FILE" <<EOF
[host_machine]
system = 'darwin'
endian = 'little'
cpu_family = '$HOST_MACHINE_CPU_FAMILY'
cpu = '$HOST_MACHINE_CPU_NAME'

[binaries]
c = '$CC'
cpp = '$CXX'
ar = '$AR'
strip = '$STRIP'
cmake = '$CMAKE'
pkg-config = '$PKG_CONFIG'

# https://mesonbuild.com/Machine-files.html#meson-builtin-options
[built-in options]
c_args = $(to_meson_array $CFLAGS $CPPFLAGS)
c_link_args = $(to_meson_array $LDFLAGS)
cpp_args = $(to_meson_array $CXXFLAGS $CPPFLAGS)
cpp_link_args = $(to_meson_array $LDFLAGS)

[properties]
sys_root = ''
EOF

    if [ "$PACKAGE_USE_BSYSTEM_CMAKE" = 1 ] ; then
        cat >> "$MESON_CROSS_FILE" <<EOF
cmake_toolchain_file='$CMAKE_TOOLCHAIN_FILE'
EOF
    fi

    MESON_SETUP_ARGS="--prefix=$PACKAGE_INSTALL_DIR --buildtype=$PROFILE --backend=ninja --pkg-config-path=$PKG_CONFIG_PATH --build.pkg-config-path=$PKG_CONFIG_PATH_FOR_BUILD --cross-file=$MESON_CROSS_FILE -Dlibdir=lib"

    MESON_SETUP_ARGS="$MESON_SETUP_ARGS -Ddefault_library=both"

    if [ "$XCPKG_CREATE_MOSTLY_STATICALLY_LINKED_EXECUTABLE" = 1 ] ; then
        MESON_SETUP_ARGS="$MESON_SETUP_ARGS --prefer-static"
    fi

    if [ "$VERBOSE_MESON" = 1 ] ; then
        MESON_COMPILE_ARGS="$MESON_COMPILE_ARGS -v"
    fi

    MESON_COMPILE_ARGS="-C $PACKAGE_BCACHED_DIR -j $BUILD_NJOBS"
    MESON_INSTALL_ARGS="-C $PACKAGE_BCACHED_DIR"

    run "$MESON" setup   "$MESON_SETUP_ARGS" "$@" "$PACKAGE_BCACHED_DIR" "$PACKAGE_BSCRIPT_DIR" &&
    run "$MESON" compile "$MESON_COMPILE_ARGS" &&
    run "$MESON" install "$MESON_INSTALL_ARGS"

}

to_meson_array() {
    RESULT="[''"
    for item in "$@"
    do
        RESULT="$RESULT, '$item'"
    done
    RESULT="$RESULT]"
    printf '%s\n' "$RESULT"
}

# }}}
##############################################################################
# {{{ cargow

cargow() {
    if [ "$CI" = true ] ; then
        run rustup default stable
        run rustup update  stable
    fi

    run rustup target add "$RUST_TARGET"

    case $1 in
        build)
            # https://doc.rust-lang.org/cargo/commands/cargo-clean.html
            # https://doc.rust-lang.org/cargo/commands/cargo-build.html

            unset CARGO_BUILD_ARGS
            unset CARGO_BUILD_ARG_VV
            unset CARGO_BUILD_ARG_TARGET
            unset CARGO_BUILD_ARG_RELEASE

            for arg in "$@"
            do
                case $arg in
                    --vv)      CARGO_BUILD_ARG_VV='set'      ;;
                    --target)  CARGO_BUILD_ARG_TARGET='set'  ;;
                    --release) CARGO_BUILD_ARG_RELEASE='set' ;;
                esac
            done

            CARGO_BUILD_ARGS="$@"

            if [ -z "$CARGO_BUILD_ARG_VV" ] && [ "$VERBOSE_CARGO" = 1 ] ; then
                CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS -v"
            fi

            if [ -z "$CARGO_BUILD_ARG_VV" ] && [ "$DEBUG_CARGO" = 1 ] ; then
                CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS -vv"
            fi

            if [ -z "$CARGO_BUILD_ARG_RELEASE" ] ; then
                CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS --release"
            fi

            if [ -z "$CARGO_BUILD_ARG_TARGET" ] ; then
                CARGO_BUILD_ARGS="$CARGO_BUILD_ARGS --target $RUST_TARGET"
            fi

            run cargo clean && run cargo $CARGO_BUILD_ARGS
            ;;
        install)
            # https://doc.rust-lang.org/cargo/commands/cargo-clean.html
            # https://doc.rust-lang.org/cargo/commands/cargo-install.html

            unset CARGO_INSTALL_ARGS
            unset CARGO_INSTALL_ARG_TARGET
            unset CARGO_INSTALL_ARG_PATH
            unset CARGO_INSTALL_ARG_ROOT
            unset CARGO_INSTALL_ARG_VV

            for arg in "$@"
            do
                case $arg in
                    --target) CARGO_INSTALL_ARG_TARGET='set' ;;
                    --path)   CARGO_INSTALL_ARG_PATH='set'   ;;
                    --root)   CARGO_INSTALL_ARG_ROOT='set'   ;;
                    --vv)     CARGO_INSTALL_ARG_VV='set'     ;;
                esac
            done

            CARGO_INSTALL_ARGS="$@"

            if [ -z "$CARGO_INSTALL_ARG_VV" ] && [ "$VERBOSE_CARGO" = 1 ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS -v"
            fi

            if [ -z "$CARGO_INSTALL_ARG_VV" ] && [ "$DEBUG_CARGO" = 1 ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS -vv"
            fi

            if [ -z "$CARGO_INSTALL_ARG_TARGET" ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --target $RUST_TARGET"
            fi

            if [ -z "$CARGO_INSTALL_ARG_PATH" ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --path $PACKAGE_BSCRIPT_DIR"
            fi

            if [ -z "$CARGO_INSTALL_ARG_ROOT" ] ; then
                CARGO_INSTALL_ARGS="$CARGO_INSTALL_ARGS --root=$PACKAGE_INSTALL_DIR"
            fi

            run cargo clean && run cargo $CARGO_INSTALL_ARGS
            ;;
        cbuild|cinstall)
            unset CARGO_CINSTALL_ARGS
            unset CARGO_CINSTALL_ARG_Q
            unset CARGO_CINSTALL_ARG_V
            unset CARGO_CINSTALL_ARG_VV
            unset CARGO_CINSTALL_ARG_DEBUG
            unset CARGO_CINSTALL_ARG_RELEASE
            unset CARGO_CINSTALL_ARG_TARGET
            unset CARGO_CINSTALL_ARG_PREFIX

            for arg in "$@"
            do
                case $arg in
                    -q|--quiet)   CARGO_CINSTALL_ARG_Q='set'       ;;
                    -v|--verbose) CARGO_CINSTALL_ARG_V='set'       ;;
                    -vv)          CARGO_CINSTALL_ARG_VV='set'      ;;
                    --debug)      CARGO_CINSTALL_ARG_DEBUG='set'   ;;
                    --release)    CARGO_CINSTALL_ARG_RELEASE='set' ;;
                    --target)     CARGO_CINSTALL_ARG_TARGET='set'  ;;
                    --prefix)     CARGO_CINSTALL_ARG_PREFIX='set'  ;;
                esac
            done

            CARGO_CINSTALL_ARGS="$@"

            if [ "$VERBOSE_CARGO" = 1 ] ; then
                if [ -z "$CARGO_CINSTALL_ARG_Q" ] && [ -z "$CARGO_CINSTALL_ARG_V" ] && [ -z "$CARGO_CINSTALL_ARG_VV" ] ; then
                    CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS -v"
                fi
            fi

            if [ "$DEBUG_CARGO" = 1 ] ; then
                if [ -z "$CARGO_CINSTALL_ARG_Q" ] && [ -z "$CARGO_CINSTALL_ARG_V" ] && [ -z "$CARGO_CINSTALL_ARG_VV" ] ; then
                    CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS -vv"
                fi
            fi

            if [ -z "$CARGO_CINSTALL_ARG_DEBUG" ] && [ -z "$CARGO_CINSTALL_ARG_RELEASE" ] ; then
                CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --release"
            fi

            if [ -z "$CARGO_CINSTALL_ARG_TARGET" ] ; then
                CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --target $RUST_TARGET"
            fi

            if [ -z "$CARGO_CINSTALL_ARG_PREFIX" ] ; then
                CARGO_CINSTALL_ARGS="$CARGO_CINSTALL_ARGS --prefix $PACKAGE_INSTALL_DIR"
            fi

            run cargo $CARGO_CINSTALL_ARGS
            ;;
        *) cargo "$@"
    esac
}

# }}}
##############################################################################
# {{{ gow

gow() {
    if [ "$VERBOSE_GO" = 1 ] ; then
        run "go env | bat --language=bash --paging=never --style=plain"
    fi

    # https://pkg.go.dev/cmd/go
    # https://pkg.go.dev/cmd/link

    unset GO_BUILD_ARGS
    unset GO_BUILD_ARGV_V
    unset GO_BUILD_ARGV_X
    unset GO_BUILD_ARGV_O
    unset GO_BUILD_ARGV_MOD
    unset GO_BUILD_ARGV_TAGS
    unset GO_BUILD_ARGV_LDFLAGS

    unset GO_BUILD_ARGS_EXTRA

    while [ -n "$1" ]
    do
        case $1 in
            -v) shift ; GO_BUILD_ARGV_V='-v' ;;
            -x) shift ; GO_BUILD_ARGV_X='-x' ;;
            -o) shift ; GO_BUILD_ARGV_O="$1" ; shift ;;
            -X) shift
                if [ -z "$GO_BUILD_ARGV_LDFLAGS" ] ; then
                    GO_BUILD_ARGV_LDFLAGS="-X $1"
                else
                    GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -X $1"
                fi
                shift
                ;;
            -ldflags)
                shift
                if [ -z "$GO_BUILD_ARGV_LDFLAGS" ] ; then
                    GO_BUILD_ARGV_LDFLAGS="$1"
                else
                    GO_BUILD_ARGV_LDFLAGS="$1 $GO_BUILD_ARGV_LDFLAGS"
                fi
                shift
                ;;
            *)  GO_BUILD_ARGS_EXTRA="$GO_BUILD_ARGS_EXTRA $1" ; shift
        esac
    done

    GO_BUILD_ARGS='-trimpath'

    if [ -z "$GO_BUILD_ARGV_V" ] ; then
        if [ "$VERBOSE_GO" = 1 ] ; then
            GO_BUILD_ARGS="$GO_BUILD_ARGS -v"
        fi
    else
        GO_BUILD_ARGS="$GO_BUILD_ARGS -v"
    fi

    if [ -z "$GO_BUILD_ARGV_X" ] ; then
        if [ "$DEBUG_GO" = 1 ] ; then
            GO_BUILD_ARGS="$GO_BUILD_ARGS -x"
        fi
    else
        GO_BUILD_ARGS="$GO_BUILD_ARGS -x"
    fi

    if [ "$PROFILE" = release ] ; then
        GO_BUILD_ARGV_LDFLAGS="$GO_BUILD_ARGV_LDFLAGS -s -w"
    fi

    GO_BUILD_ARGS="$GO_BUILD_ARGS -ldflags '$GO_BUILD_ARGV_LDFLAGS'"

    if [ -z "$GO_BUILD_ARGV_O" ] ; then
        GO_BUILD_ARGS="$GO_BUILD_ARGS -o $PACKAGE_BCACHED_DIR/"
    else
        GO_BUILD_ARGS="$GO_BUILD_ARGS -o $PACKAGE_BCACHED_DIR/$GO_BUILD_ARGV_O"
    fi

    GO_BUILD_ARGS="$GO_BUILD_ARGS $GO_BUILD_ARGS_EXTRA"

    # shellcheck disable=SC2086
    run go build $GO_BUILD_ARGS

    for item in $(ls "$PACKAGE_BCACHED_DIR")
    do
        case $item in
            *.a)     run install_libs "$PACKAGE_BCACHED_DIR/$item" ;;
            *.dylib) run install_libs "$PACKAGE_BCACHED_DIR/$item" ;;
            *)       run install_bins "$PACKAGE_BCACHED_DIR/$item" ;;
        esac
    done
}

# }}}
##############################################################################
# {{{ inspect_package_spec

# inspect_package_spec <PACKAGE-NAME|PACKAGE-SPEC> [DEFAULT-TARGET]
  inspect_package_spec() {
    case $1 in
        '') abort 1 "package-name or package-spec is unspecified."
            ;;
        */*)
            PACKAGE_NAME="${1##*/}"

            if [ -z "$PACKAGE_NAME" ] ; then
                abort 1 "invalid package-spec: $1\npackage-name is unspecified."
            elif printf '%s\n' "$PACKAGE_NAME" | grep -q -E '^[A-Za-z0-9+-._@]{1,50}$' ; then
                :
            else
                abort 1 "invalid package-spec: $1\npackage-name does not match pattern ^[A-Za-z0-9+-._@]{1,50}$"
            fi

            TARGET_PLATFORM_SPEC="${1%/*}"

            TARGET_PLATFORM_NAME=
            TARGET_PLATFORM_VERS=
            TARGET_PLATFORM_ARCH=

            TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
            TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
            TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

            if [ -z "$TARGET_PLATFORM_NAME" ] ; then
                abort 1 "invalid package-spec: $1\nplatform-name is unspecified."
            fi

            TARGET_PLATFORM_NAME_IS_SUPPORTED=0

            if [ -z "$XCODE_PLATFORM_NAMES" ] ; then
                XCODE_PLATFORM_NAMES='MacOSX DriverKit WatchOS WatchSimulator iPhoneOS iPhoneSimulator AppleTVOS AppleTVSimulator XROS XRSimulator'
            fi

            for XCODE_PLATFORM_NAME in $XCODE_PLATFORM_NAMES
            do
                if [ "$XCODE_PLATFORM_NAME" = "$TARGET_PLATFORM_NAME" ] ; then
                    TARGET_PLATFORM_NAME_IS_SUPPORTED=1
                    break;
                fi
            done

            if [ "$TARGET_PLATFORM_NAME_IS_SUPPORTED" = 0 ] ; then
                abort 1 "invalid package-spec: $1\nunsupported-platform: $TARGET_PLATFORM_NAME"
            fi

            if [ -z "$TARGET_PLATFORM_VERS" ] ; then
                abort 1 "invalid package-spec: $1\nplatform-version is unspecified."
            fi

            if [ -z "$TARGET_PLATFORM_ARCH" ] ; then
                abort 1 "invalid package-spec: $1\nplatform-arch is unspecified."
            fi

            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"
            printf '%s\n' "$PACKAGE_SPEC"
            ;;
        *)  if printf '%s\n' "$1" | grep -q -E '^[A-Za-z0-9+-._@]{1,50}$' ; then
                case $2 in
                    '') ;;
                    *-*-*-*)
                        abort 1 "you have specified --target=$2 , but it is an invalid target."
                        ;;
                    *-*-*)
                        TARGET_PLATFORM_NAME=
                        TARGET_PLATFORM_VERS=
                        TARGET_PLATFORM_ARCH=

                        TARGET_PLATFORM_NAME="$(printf '%s\n' "$2" | cut -d- -f1)"
                        TARGET_PLATFORM_VERS="$(printf '%s\n' "$2" | cut -d- -f2)"
                        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$2" | cut -d- -f3)"

                        if [ -z "$TARGET_PLATFORM_NAME" ] ; then
                            abort 1 "you have specified --target=$2 , but it is an invalid target."
                        fi

                        TARGET_PLATFORM_NAME_IS_SUPPORTED=0

                        if [ -z "$XCODE_PLATFORM_NAMES" ] ; then
                            XCODE_PLATFORM_NAMES='MacOSX DriverKit WatchOS WatchSimulator iPhoneOS iPhoneSimulator AppleTVOS AppleTVSimulator XROS XRSimulator'
                        fi

                        for XCODE_PLATFORM_NAME in $XCODE_PLATFORM_NAMES
                        do
                            if [ "$XCODE_PLATFORM_NAME" = "$TARGET_PLATFORM_NAME" ] ; then
                                TARGET_PLATFORM_NAME_IS_SUPPORTED=1
                                break;
                            fi
                        done

                        if [ "$TARGET_PLATFORM_NAME_IS_SUPPORTED" = 0 ] ; then
                            abort 1 "you have specified --target=$2 , but it is an invalid target. unrecognized platform-name: $TARGET_PLATFORM_NAME"
                        fi

                        if [ -z "$TARGET_PLATFORM_VERS" ] ; then
                            abort 1 "you have specified --target=$2 , but it is an invalid target."
                        fi

                        if [ -z "$TARGET_PLATFORM_ARCH" ] ; then
                            abort 1 "you have specified --target=$2 , but it is an invalid target."
                        fi

                        TARGET_PLATFORM_SPEC="$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ARCH"
                        PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$1"

                        #note "$1 will be treated as a package-name, and it will be expanded to $PACKAGE_SPEC"
                        printf '%s\n' "$PACKAGE_SPEC"
                        return 0
                        ;;
                    *)  abort 1 "you have specified --target=$2 , but it is an invalid target."
                esac

                case $XCPKG_DEFAULT_TARGET in
                    '')
                        TARGET_PLATFORM_NAME="$NATIVE_PLATFORM_NAME"
                        TARGET_PLATFORM_VERS="${NATIVE_PLATFORM_VERS%.*}"
                        TARGET_PLATFORM_ARCH="$NATIVE_PLATFORM_ARCH"

                        TARGET_PLATFORM_SPEC="$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ARCH"

                        PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$1"
                        ;;
                    *-*-*-*)
                        abort 1 "you have set XCPKG_DEFAULT_TARGET=$XCPKG_DEFAULT_TARGET , but it is an invalid target."
                        ;;
                    *-*-*)
                        TARGET_PLATFORM_NAME=
                        TARGET_PLATFORM_VERS=
                        TARGET_PLATFORM_ARCH=

                        TARGET_PLATFORM_NAME="$(printf '%s\n' "$XCPKG_DEFAULT_TARGET" | cut -d- -f1)"
                        TARGET_PLATFORM_VERS="$(printf '%s\n' "$XCPKG_DEFAULT_TARGET" | cut -d- -f2)"
                        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$XCPKG_DEFAULT_TARGET" | cut -d- -f3)"

                        if [ -z "$TARGET_PLATFORM_NAME" ] ; then
                            abort 1 "you have set XCPKG_DEFAULT_TARGET=$XCPKG_DEFAULT_TARGET , but it is an invalid package spec."
                        fi

                        TARGET_PLATFORM_NAME_IS_SUPPORTED=0

                        if [ -z "$XCODE_PLATFORM_NAMES" ] ; then
                            XCODE_PLATFORM_NAMES='MacOSX DriverKit WatchOS WatchSimulator iPhoneOS iPhoneSimulator AppleTVOS AppleTVSimulator XROS XRSimulator'
                        fi

                        for XCODE_PLATFORM_NAME in $XCODE_PLATFORM_NAMES
                        do
                            if [ "$XCODE_PLATFORM_NAME" = "$TARGET_PLATFORM_NAME" ] ; then
                                TARGET_PLATFORM_NAME_IS_SUPPORTED=1
                                break;
                            fi
                        done

                        if [ "$TARGET_PLATFORM_NAME_IS_SUPPORTED" = 0 ] ; then
                            abort 1 "you have set XCPKG_DEFAULT_TARGET=$XCPKG_DEFAULT_TARGET , but it is an invalid target. unrecognized platform-name: $TARGET_PLATFORM_NAME"
                        fi

                        if [ -z "$TARGET_PLATFORM_VERS" ] ; then
                            abort 1 "you have set XCPKG_DEFAULT_TARGET=$XCPKG_DEFAULT_TARGET , but it is an invalid target."
                        fi

                        if [ -z "$TARGET_PLATFORM_ARCH" ] ; then
                            abort 1 "you have set XCPKG_DEFAULT_TARGET=$XCPKG_DEFAULT_TARGET , but it is an invalid target."
                        fi

                        TARGET_PLATFORM_SPEC="$TARGET_PLATFORM_NAME-$TARGET_PLATFORM_VERS-$TARGET_PLATFORM_ARCH"
                        PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$1"
                        ;;
                    *) abort 1 "you have set XCPKG_DEFAULT_TARGET=$XCPKG_DEFAULT_TARGET , but it is an invalid target."
                esac

                #note "$1 will be treated as a package-name, and it will be expanded to $PACKAGE_SPEC"
                printf '%s\n' "$PACKAGE_SPEC"
            else
                abort 1 "invalid package-name: $1\npackage-name does not match pattern ^[A-Za-z0-9+-._@]{1,50}$"
            fi
    esac
}

# }}}
##############################################################################
# {{{ inspect_install_arguments

inspect_install_arguments() {
    LOG_LEVEL_QUIET=0
    LOG_LEVEL_NORMAL=1
    LOG_LEVEL_VERBOSE=2
    LOG_LEVEL_VERY_VERBOSE=3

    unset PROFILE

    unset LOG_LEVEL

    unset BUILD_NJOBS

    unset ENABLE_LTO

    unset ENABLE_STRIP

    unset ENABLE_CCACHE

    unset UPGRADE_IF_POSSIBLE

    unset EXPORT_COMPILE_COMMANDS_JSON

    unset KEEP_SESSION_DIR

    unset SPECIFIED_FORMULA_SEARCH_DIRS

    unset SPECIFIED_DEVELOPER_DIR

    unset SPECIFIED_PACKAGE_LIST

    unset SPECIFIED_TARGET

    unset DUMP_ENV
    unset DUMP_SED
    unset DUMP_HTTP
    unset DUMP_UPPM
    unset DUMP_XCODE
    unset DUMP_FORMULA

    unset VERBOSE_GO
    unset VERBOSE_CARGO
    unset VERBOSE_MESON
    unset VERBOSE_NINJA
    unset VERBOSE_GMAKE
    unset VERBOSE_CMAKE
    unset VERBOSE_XMAKE

    unset DEBUG_CC
    unset DEBUG_LD
    unset DEBUG_GO
    unset DEBUG_CARGO
    unset DEBUG_GMAKE
    unset DEBUG_CMAKE
    unset DEBUG_XMAKE
    unset DEBUG_PKG_CONFIG

    while [ -n "$1" ]
    do
        case $1 in
            -q) LOG_LEVEL=0 ;;
            -v) LOG_LEVEL=2

                DUMP_SED=1
                DUMP_ENV=1
                DUMP_HTTP=1
                DUMP_UPPM=1
                DUMP_XCODE=1
                DUMP_FORMULA=1

                VERBOSE_GO=1
                VERBOSE_CARGO=1
                VERBOSE_MESON=1
                VERBOSE_GMAKE=1
                VERBOSE_CMAKE=1
                VERBOSE_XMAKE=1
                VERBOSE_NINJA=1
                ;;
            -x) LOG_LEVEL=3

                DUMP_SED=1
                DUMP_ENV=1
                DUMP_HTTP=1
                DUMP_UPPM=1
                DUMP_XCODE=1
                DUMP_FORMULA=1

                VERBOSE_MESON=1
                VERBOSE_NINJA=1
                VERBOSE_GMAKE=1
                VERBOSE_CMAKE=1
                VERBOSE_XMAKE=1

                DEBUG_CC=1
                DEBUG_LD=1
                DEBUG_GO=1
                DEBUG_CARGO=1
                DEBUG_GMAKE=1
                DEBUG_CMAKE=1
                DEBUG_XMAKE=1
                DEBUG_PKG_CONFIG=1
                ;;
            -v-env)
                DUMP_ENV=1
                ;;
            -v-http)
                DUMP_HTTP=1
                ;;
            -v-uppm)
                DUMP_UPPM=1
                ;;
            -v-xcode)
                DUMP_XCODE=1
                ;;
            -v-formula)
                DUMP_FORMULA=1
                ;;
            -v-go)
                VERBOSE_GO=1
                ;;
            -v-cargo)
                VERBOSE_CARGO=1
                ;;
            -v-meson)
                VERBOSE_MESON=1
                ;;
            -v-ninja)
                VERBOSE_NINJA=1
                ;;
            -v-gmake)
                VERBOSE_GMAKE=1
                ;;
            -v-cmake)
                VERBOSE_CMAKE=1
                ;;
            -v-xmake)
                VERBOSE_XMAKE=1
                ;;
            -x-sh)
                set -x
                ;;
            -x-cc)
                DEBUG_CC=1
                ;;
            -x-ld)
                DEBUG_LD=1
                ;;
            -x-go)
                DEBUG_GO=1
                ;;
            -x-cargo)
                DEBUG_CARGO=1
                ;;
            -x-gmake)
                DEBUG_GMAKE=1
                ;;
            -x-cmake)
                DEBUG_CMAKE=1
                ;;
            -x-xmake)
                DEBUG_XMAKE=1
                ;;
            -x-pkg-config)
                DEBUG_PKG_CONFIG=1
                ;;

            --disable-ccache)
                ENABLE_CCACHE=0
                ;;
            --enable-lto)
                ENABLE_LTO=1
                ;;
            --enable-strip)
                ENABLE_STRIP=all
                ;;
            --enable-strip=*)
                ENABLE_STRIP="${1#*=}"
                case $ENABLE_STRIP in
                    no|all|debug|unneeded) ;;
                    *)  abort 1 "--strip=<VALUE>, VALUE must be one of no, all, debug, unneeded"
                esac
                ;;
            --target=*)
                SPECIFIED_TARGET="${1#*=}"
                ;;
            --developer-dir=*)
                SPECIFIED_DEVELOPER_DIR="${1#*=}"
                ;;
            --profile=*)
                PROFILE="${1#*=}"
                ;;
            -j) shift
                isInteger "$1" || abort 1 "-j <N>, <N> must be an integer."
                BUILD_NJOBS="$1"
                ;;
            -I) shift
                [ -z "$1" ] && abort 1 "-I <FORMULA-SEARCH-DIR> , <FORMULA-SEARCH-DIR> is unspecified."
                [ -e "$1" ] || abort 1 "'$1' was expected to be exist, but it was not."
                [ -d "$1" ] || abort 1 "'$1' was expected to be a directory, but it was not."
                FORMULA_SEARCH_DIR="$(realpath "$1")"
                SPECIFIED_FORMULA_SEARCH_DIRS="$SPECIFIED_FORMULA_SEARCH_DIRS:$FORMULA_SEARCH_DIR"
                ;;
            -K) KEEP_SESSION_DIR=1 ;;
            -U) UPGRADE_IF_POSSIBLE=1 ;;
            -E) EXPORT_COMPILE_COMMANDS_JSON=1 ;;

            -*) abort 1 "unrecognized option: $1"
                ;;
            *)  SPECIFIED_PACKAGE_LIST="$SPECIFIED_PACKAGE_LIST $1"
        esac
        shift
    done

    #########################################################################################

    if [ -z "$XCPKG_FORMULA_SEARCH_DIRS" ] ; then
        XCPKG_FORMULA_SEARCH_DIRS="${SPECIFIED_FORMULA_SEARCH_DIRS#:}"
    else
        XCPKG_FORMULA_SEARCH_DIRS="${SPECIFIED_FORMULA_SEARCH_DIRS#:}:$XCPKG_FORMULA_SEARCH_DIRS"
    fi

    #########################################################################################

    if [ -z "$SPECIFIED_DEVELOPER_DIR" ] ; then
        __inspect_xcode_info
    else
        __inspect_xcode_info "$SPECIFIED_DEVELOPER_DIR"
    fi

    if [ "$DUMP_XCODE" = 1 ] ; then
        __println_xcode_info
    fi

    #########################################################################################

    unset SPECIFIED_PACKAGE_SPEC_LIST

    for PACKAGE in $SPECIFIED_PACKAGE_LIST
    do
        PACKAGE_SPEC=
        PACKAGE_SPEC="$(inspect_package_spec "$PACKAGE" $SPECIFIED_TARGET)"

        if [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] ; then
            SPECIFIED_PACKAGE_SPEC_LIST="$PACKAGE_SPEC"
        else
            SPECIFIED_PACKAGE_SPEC_LIST="$SPECIFIED_PACKAGE_SPEC_LIST $PACKAGE_SPEC"
        fi
    done

    #########################################################################################

    if [ "$LOG_LEVEL" = 0 ] ; then
        exec 1>/dev/null
        exec 2>&1
    else
        if [ -z "$LOG_LEVEL" ] ; then
            LOG_LEVEL=1
        fi
    fi

    #########################################################################################

    if [ -z "$PROFILE" ] ; then
        PROFILE=release
    fi

    if [ -z "$BUILD_NJOBS" ] ; then
        BUILD_NJOBS="$NATIVE_PLATFORM_NCPU"
    fi

    #########################################################################################

    if [ -z "$ENABLE_STRIP" ] ; then
        case $PROFILE in
            debug)   ENABLE_STRIP=no  ;;
            release) ENABLE_STRIP=all ;;
        esac
    fi

    #########################################################################################

    # DO NOT use these environment variables
    # https://cmake.org/cmake/help/latest/envvar/MACOSX_DEPLOYMENT_TARGET.html
    unset   MACOSX_DEPLOYMENT_TARGET
    unset IPHONEOS_DEPLOYMENT_TARGET
    unset  WATCHOS_DEPLOYMENT_TARGET

    # https://www.real-world-systems.com/docs/xcrun.1.html
    unset SDKROOT

    # https://stackoverflow.com/questions/18476490/what-is-purpose-of-target-arch-variable-in-makefiles
    unset TARGET_ARCH

    unset LIBS

    #########################################################################################

    # these environment variable is used by wrapper-target-*
    export XCPKG_CC="$XCODE_CC"
    export XCPKG_CXX="$XCODE_CXX"
    export XCPKG_OBJC="$XCODE_CC"

    #########################################################################################

         CC_FOR_BUILD="$XCPKG_CORE_DIR/wrapper-native-cc"
        CXX_FOR_BUILD="$XCPKG_CORE_DIR/wrapper-native-c++"
       OBJC_FOR_BUILD="$XCPKG_CORE_DIR/wrapper-native-objc"
        CPP_FOR_BUILD="$CC_FOR_BUILD -E"
         AS_FOR_BUILD="$XCODE_AS"
         AR_FOR_BUILD="$XCODE_AR"
     RANLIB_FOR_BUILD="$XCODE_RANLIB"
         LD_FOR_BUILD="$XCODE_LD"
         NM_FOR_BUILD="$XCODE_NM"
       SIZE_FOR_BUILD="$XCODE_SIZE"
      STRIP_FOR_BUILD="$XCODE_STRIP"
    STRINGS_FOR_BUILD="$XCODE_STRINGS"
    OBJDUMP_FOR_BUILD="$XCODE_OBJDUMP"

    eval "SYSROOT_FOR_BUILD=\"\$XCODE_${NATIVE_PLATFORM_NAME}_SDKROOT\""

    for TOOL in CC OBJC CXX CPP AS AR RANLIB LD NM STRIP SIZE STRINGS OBJDUMP SYSROOT
    do
        export "${TOOL}_FOR_BUILD"
    done

    #########################################################################################

    if [ "$DEBUG_CC" = 1 ] ; then
        # this environment variable is used by target-wrapper-*
        export XCPKG_VERBOSE=1
    else
        unset  XCPKG_VERBOSE
    fi

    #########################################################################################

    # these environment variable is used by wrapper-native-*
    export XCPKG_NATIVE_FLAGS="-isysroot $SYSROOT_FOR_BUILD -mmacosx-version-min=$NATIVE_PLATFORM_VERS -arch $NATIVE_PLATFORM_ARCH -Qunused-arguments"

    export    CFLAGS_FOR_BUILD=''
    export OBJCFLAGS_FOR_BUILD=''
    export  CXXFLAGS_FOR_BUILD=''
    export  CPPFLAGS_FOR_BUILD=''
    export   LDFLAGS_FOR_BUILD=''

    if [ "$DEBUG_CC" = 1 ] ; then
          CFLAGS_FOR_BUILD="$CFLAGS_FOR_BUILD -v"
        CXXFLAGS_FOR_BUILD="$CXXFLAGS_FOR_BUILD -v"
       OBJCFLAGS_FOR_BUILD="$OBJCFLAGS_FOR_BUILD -v"
    fi

    if [ "$DEBUG_LD" = 1 ] ; then
         LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -Wl,-v"
    fi

    if [ "$PROFILE" = release ] ; then
          CFLAGS_FOR_BUILD="$CFLAGS_FOR_BUILD -Os"
        CXXFLAGS_FOR_BUILD="$CXXFLAGS_FOR_BUILD -Os"
       OBJCFLAGS_FOR_BUILD="$OBJCFLAGS_FOR_BUILD -Os"
         LDFLAGS_FOR_BUILD="$LDFLAGS_FOR_BUILD -Wl,-S"
    fi

    #########################################################################################

    export      CC="$CC_FOR_BUILD"
    export    OBJC="$OBJC_FOR_BUILD"
    export     CXX="$CXX_FOR_BUILD"
    export     CPP="$CPP_FOR_BUILD"
    export      AS="$AS_FOR_BUILD"
    export      AR="$AR_FOR_BUILD"
    export  RANLIB="$RANLIB_FOR_BUILD"
    export      LD="$LD_FOR_BUILD"
    export      NM="$NM_FOR_BUILD"
    export    SIZE="$SIZE_FOR_BUILD"
    export   STRIP="$STRIP_FOR_BUILD"
    export STRINGS="$STRINGS_FOR_BUILD"
    export OBJDUMP="$OBJDUMP_FOR_BUILD"

    export    CFLAGS="$CFLAGS_FOR_BUILD"
    export OBJCFLAGS="$OBJCFLAGS_FOR_BUILD"
    export  CXXFLAGS="$CXXFLAGS_FOR_BUILD"
    export  CPPFLAGS="$CPPFLAGS_FOR_BUILD"
    export   LDFLAGS="$LDFLAGS_FOR_BUILD"
}

# }}}
##############################################################################
# {{{ xcpkg install

__install_the_given_packages() {
    inspect_install_arguments "$@"

    [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] && abort 1 "$XCPKG_ARG0 install <PACKAGE-SPEC|PACKAGE-NAME>..., <|PACKAGE-SPEC|PACKAGE-NAME> is unspecified."

    #########################################################################################

    SESSION_DIR="$XCPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"

    #########################################################################################

    # 1. check if has circle
    # 2. backup formulas
    # 3. cache variables

    for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then
                continue
            fi

            __load_formula_of_the_given_package "$PACKAGE_NAME"

            cp -L "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml"

            eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'"

            for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
            do
                if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                    abort 1 "package '$PACKAGE_NAME' depends itself."
                fi

                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME"
                fi
            done
        done
    done

    #########################################################################################

    for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${SPECIFIED_PACKAGE_SPEC%/*}"

        TARGET_PLATFORM_NAME=
        TARGET_PLATFORM_VERS=
        TARGET_PLATFORM_ARCH=

        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        ##################################################################

        REQUESTED_PACKAGE_NAME_LIST=

        PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            ##################################################################

            REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME"

            for item in $REQUESTED_PACKAGE_NAME_LIST
            do
                [ "$item" = "$PACKAGE_NAME" ] && continue
                REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item"
            done

            REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2"

            ##################################################################

            PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')"

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$item"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
                fi
            done
        done

        ##################################################################

        for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST
        do
            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"

            if is_package_installed "$PACKAGE_SPEC" ; then
                if [ "$UPGRAGE" = 1 ] ; then
                    if is_package__outdated "$PACKAGE_SPEC" ; then
                        (__install_the_given_package "$PACKAGE_SPEC")
                    else
                        if [ "$LOG_LEVEL" -ne 0 ] ; then
                            printf "$COLOR_GREEN%-10s$COLOR_OFF already have been installed and is up-to-date.\n" "$PACKAGE_SPEC"
                        fi
                    fi
                else
                    if [ "$LOG_LEVEL" -ne 0 ] ; then
                        printf "$COLOR_GREEN%-10s$COLOR_OFF already have been installed.\n" "$PACKAGE_SPEC"
                    fi
                fi
            else
                (__install_the_given_package "$PACKAGE_SPEC")
            fi
        done
    done

    #########################################################################################

    if [ "$KEEP_SESSION_DIR" != 1 ] ; then
        rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ xcpkg reinstall

__reinstall_the_given_packages() {
    inspect_install_arguments "$@"

    [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] && abort 1 "neither package-name nor package-spec is specified."

    #########################################################################################

    SESSION_DIR="$XCPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"

    #########################################################################################

    # 1. check if has circle
    # 2. backup formulas
    # 3. cache variables

    for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then
                continue
            fi

            __load_formula_of_the_given_package "$PACKAGE_NAME"

            cp -L "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml"

            eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'"

            for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
            do
                if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                    abort 1 "package '$PACKAGE_NAME' depends itself."
                fi

                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME"
                fi
            done
        done
    done

    #########################################################################################

    for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${SPECIFIED_PACKAGE_SPEC%/*}"

        TARGET_PLATFORM_NAME=
        TARGET_PLATFORM_VERS=
        TARGET_PLATFORM_ARCH=

        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        ##################################################################

        REQUESTED_PACKAGE_NAME_LIST=

        PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            ##################################################################

            REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME"

            for item in $REQUESTED_PACKAGE_NAME_LIST
            do
                [ "$item" = "$PACKAGE_NAME" ] && continue
                REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item"
            done

            REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2"

            ##################################################################

            PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')"

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$item"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
                fi
            done
        done

        ##################################################################

        for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST
        do
            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"

            PACKAGE_INSTALLED_LINK_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
            PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")"

            (__install_the_given_package "$PACKAGE_SPEC")

            rm -rf "$PACKAGE_INSTALLED_REAL_DIR"
        done
    done

    #########################################################################################

    if [ "$KEEP_SESSION_DIR" != 1 ] ; then
        rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ xcpkg upgrade

__upgrade_packages() {
    inspect_install_arguments "$@"

    if [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] ; then
        SPECIFIED_PACKAGE_SPEC_LIST=$(__list__outdated_packages)
    fi

    if [ -z "$SPECIFIED_PACKAGE_SPEC_LIST" ] ; then
        return 0
    fi

    #########################################################################################

    SESSION_DIR="$XCPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"

    #########################################################################################

    # 1. check if has circle
    # 2. backup formulas
    # 3. cache variables

    for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            if [ -f "$SESSION_DIR/$PACKAGE_NAME.yml" ] ; then
                continue
            fi

            __load_formula_of_the_given_package "$PACKAGE_NAME"

            cp -L "$PACKAGE_FORMULA_FILEPATH" "$SESSION_DIR/$PACKAGE_NAME.yml"

            eval "PACKAGE_DEP_PKG_${PACKAGE_NAME_UPPERCASE_UNDERSCORE}='$PACKAGE_DEP_PKG'"

            for DEPENDENT_PACKAGE_NAME in $PACKAGE_DEP_PKG
            do
                if [ "$DEPENDENT_PACKAGE_NAME" = "$PACKAGE_NAME" ] ; then
                    abort 1 "package '$PACKAGE_NAME' depends itself."
                fi

                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$DEPENDENT_PACKAGE_NAME"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$DEPENDENT_PACKAGE_NAME"
                fi
            done
        done
    done

    #########################################################################################

    for SPECIFIED_PACKAGE_SPEC in $SPECIFIED_PACKAGE_SPEC_LIST
    do
        TARGET_PLATFORM_SPEC="${SPECIFIED_PACKAGE_SPEC%/*}"

        TARGET_PLATFORM_NAME=
        TARGET_PLATFORM_VERS=
        TARGET_PLATFORM_ARCH=

        TARGET_PLATFORM_NAME="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f1)"
        TARGET_PLATFORM_VERS="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f2)"
        TARGET_PLATFORM_ARCH="$(printf '%s\n' "$TARGET_PLATFORM_SPEC" | cut -d- -f3)"

        ##################################################################

        REQUESTED_PACKAGE_NAME_LIST=

        PACKAGE_NAME_STACK="${SPECIFIED_PACKAGE_SPEC##*/}"

        while [ -n "$PACKAGE_NAME_STACK" ]
        do
            case $PACKAGE_NAME_STACK in
                *\;*) PACKAGE_NAME="${PACKAGE_NAME_STACK##*;}" ; PACKAGE_NAME_STACK="${PACKAGE_NAME_STACK%;*}" ;;
                *)    PACKAGE_NAME="${PACKAGE_NAME_STACK}"     ; PACKAGE_NAME_STACK=
            esac

            ##################################################################

            REQUESTED_PACKAGE_NAME_LIST2="$PACKAGE_NAME"

            for item in $REQUESTED_PACKAGE_NAME_LIST
            do
                [ "$item" = "$PACKAGE_NAME" ] && continue
                REQUESTED_PACKAGE_NAME_LIST2="$REQUESTED_PACKAGE_NAME_LIST2 $item"
            done

            REQUESTED_PACKAGE_NAME_LIST="$REQUESTED_PACKAGE_NAME_LIST2"

            ##################################################################

            PACKAGE_NAME_UPPERCASE_UNDERSCORE="$(printf '%s\n' "$PACKAGE_NAME" | tr a-z A-Z | tr '@+-.' '_')"

            for item in $(eval echo \$PACKAGE_DEP_PKG_"${PACKAGE_NAME_UPPERCASE_UNDERSCORE}")
            do
                if [ -z "$PACKAGE_NAME_STACK" ] ; then
                    PACKAGE_NAME_STACK="$item"
                else
                    PACKAGE_NAME_STACK="$PACKAGE_NAME_STACK;$item"
                fi
            done
        done

        ##################################################################

        for PACKAGE_NAME in $REQUESTED_PACKAGE_NAME_LIST
        do
            PACKAGE_SPEC="$TARGET_PLATFORM_SPEC/$PACKAGE_NAME"

            is_package__outdated "$PACKAGE_SPEC" || {
                note 1 "$PACKAGE_SPEC is not outdated."
                continue
            }

            PACKAGE_INSTALLED_LINK_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"
            PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")"

            (__install_the_given_package "$PACKAGE_SPEC")

            rm -rf "$PACKAGE_INSTALLED_REAL_DIR"
        done
    done

    #########################################################################################

    if [ "$KEEP_SESSION_DIR" != 1 ] ; then
        rm -rf "$SESSION_DIR"
    fi
}

# }}}
##############################################################################
# {{{ xcpkg uninstall

__uninstall_the_given_packages() {
    [ -z "$1" ] && abort 1 "neither package-name nor package-spec is specified."

    unset PACKAGE_SPECS

    for item in "$@"
    do
        PACKAGE_SPECS="$PACKAGE_SPECS $(inspect_package_spec "$item")"
    done

    for PACKAGE_SPEC in $PACKAGE_SPECS
    do
        PACKAGE_INSTALLED_LINK_DIR="$XCPKG_PACKAGE_INSTALLED_ROOT/$PACKAGE_SPEC"

        [ -e "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 10 "package '$PACKAGE_SPEC' is not installed."
        [ -L "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 11 "$PACKAGE_INSTALLED_LINK_DIR was expected a symlink, but it was not."
        [ -d "$PACKAGE_INSTALLED_LINK_DIR" ] || abort 12 "$PACKAGE_INSTALLED_LINK_DIR was expected a symlink refer to a directory, but it was not."

        PACKAGE_INSTALLED_REAL_DIR="$(readlink -f "$PACKAGE_INSTALLED_LINK_DIR")"

        [ -d "$PACKAGE_INSTALLED_REAL_DIR" ] || abort 13 "directory $PACKAGE_INSTALLED_REAL_DIR was expected exists, but it was not."

        PACKAGE_MANIFEST_FILEPATH="$PACKAGE_INSTALLED_REAL_DIR/.xcpkg/MANIFEST.txt"

        [ -f "$PACKAGE_MANIFEST_FILEPATH" ] || abort 13 "$PACKAGE_MANIFEST_FILEPATH file was expected exist, but it was not."

        PACKAGE_RECEIPT_FILEPATH="$PACKAGE_INSTALLED_REAL_DIR/.xcpkg/RECEIPT.yml"

        [ -f "$PACKAGE_RECEIPT_FILEPATH" ] || abort 14 "$PACKAGE_RECEIPT_FILEPATH file was expected exist, but it was not."

        run rm -ff "$PACKAGE_INSTALLED_LINK_DIR"
        run rm -rf "$PACKAGE_INSTALLED_REAL_DIR"
    done
}

# }}}
##############################################################################
# {{{ xcpkg upgrade-self

# __upgrade_self <URL>
  __upgrade_self() {
    if [ -z "$1" ] ; then
        error "__upgrade_self <URL> , <URL> must be non-empty."
        return 1
    fi

    unset CURRENT_SCRIPT_REALPATH

    # if file exists and is a symbolic link
    if [ -L "$XCPKG_PATH" ] ; then
        # https://unix.stackexchange.com/questions/136494/whats-the-difference-between-realpath-and-readlink-f#:~:text=GNU%20coreutils%20introduced%20a%20realpath,in%20common%20with%20GNU%20readlink%20.
        if command -v realpath > /dev/null ; then
            CURRENT_SCRIPT_REALPATH=$(realpath "$XCPKG_PATH")
        elif command -v readlink > /dev/null && readlink -f xx > /dev/null 2>&1 ; then
            CURRENT_SCRIPT_REALPATH=$(readlink -f "$XCPKG_PATH")
        else
            CURRENT_SCRIPT_REALPATH=$(realpath "$XCPKG_PATH")
        fi
    else
        CURRENT_SCRIPT_REALPATH="$XCPKG_PATH"
    fi

    SESSION_DIR="$XCPKG_HOME/run/$$"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    wfetch "$1" -o self

    run chmod 755 self

    if [ -w "$CURRENT_SCRIPT_REALPATH" ] ; then
        run      mv self "$CURRENT_SCRIPT_REALPATH"
    else
        run sudo mv self "$CURRENT_SCRIPT_REALPATH"
    fi

    run rm -rf "$SESSION_DIR"
}

# }}}
##############################################################################
# {{{ xcpkg completion zsh

# __zsh_completions <URL> [--output-dir=<DIR>]
  __zsh_completions() {
    if [ -z "$1" ] ; then
        error "__zsh_completions <URL> [--output-dir=<DIR>] , <URL> must be non-empty."
        return 1
    else
        ZSH_COMPLETIONS_SCRIPT_URL="$1"
    fi

    shift

    unset OUTPUT_DIR

    for arg in "$@"
    do
        case $arg in
            --output-dir=*)
                OUTPUT_DIR="${arg#*=}"
                case $OUTPUT_DIR in
                    '')     abort 1 "__zsh_completions <URL> [--output-dir=<DIR>] , <DIR> must be non-empty." ;;
                    \~|\~/) OUTPUT_DIR="${HOME}" ;;
                    \~/*)   OUTPUT_DIR="$HOME/$(printf '%s\n' "$OUTPUT_DIR" | cut -c3-)" ;;
                esac
                ;;
            *)  abort 1 "__zsh_completions <URL> [--output-dir=<DIR>] , unrecognized argument: $arg"
        esac
    done

    ZSH_COMPLETIONS_SCRIPT_FILENAME="${XCPKG_ARG0##*/}"

    if [ -n "$OUTPUT_DIR" ] ; then
        ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="$OUTPUT_DIR/$ZSH_COMPLETIONS_SCRIPT_FILENAME"
    elif [ "$(uname)" = Linux ] && command -v termux-info > /dev/null && [ "$HOME" = '/data/data/com.termux/files/home' ] ; then
        ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="/data/data/com.termux/files/usr/share/zsh/site-functions/$ZSH_COMPLETIONS_SCRIPT_FILENAME"
    else
        ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH="/usr/local/share/zsh/site-functions/$ZSH_COMPLETIONS_SCRIPT_FILENAME"
    fi

    # if file exists and is a symbolic link
    if [ -L "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then
        # https://unix.stackexchange.com/questions/136494/whats-the-difference-between-realpath-and-readlink-f#:~:text=GNU%20coreutils%20introduced%20a%20realpath,in%20common%20with%20GNU%20readlink%20.
        if command -v realpath > /dev/null ; then
            ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(realpath "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")
        elif command -v readlink > /dev/null && readlink -f xx > /dev/null 2>&1 ; then
            ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(readlink -f "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")
        else
            ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH=$(realpath "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")
        fi
    fi

    SESSION_DIR="$XCPKG_HOME/run/$$"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    wfetch "$ZSH_COMPLETIONS_SCRIPT_URL" -o _xcpkg

    run chmod 644 _xcpkg

    if [ -f "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then
        if [ -w "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH" ] ; then
            run      mv _xcpkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        else
            run sudo mv _xcpkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        fi
    else
        ZSH_COMPLETIONS_SCRIPT_OUT_DIR="$(dirname "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH")"

        if [ ! -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" ] ; then
            run install -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" || run sudo install -d "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR"
        fi

        if [ -w "$ZSH_COMPLETIONS_SCRIPT_OUT_DIR" ] ; then
            run      mv _xcpkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        else
            run sudo mv _xcpkg "$ZSH_COMPLETIONS_SCRIPT_OUT_FILEPATH"
        fi
    fi

    run rm -rf "$SESSION_DIR"

    printf '\n'
    note "${COLOR_YELLOW}you may need to run command${COLOR_RED} ${COLOR_GREEN}autoload -U compinit && compinit${COLOR_OFF} ${COLOR_YELLOW}in zsh to make it work.${COLOR_OFF}"
}

# }}}
##############################################################################
# {{{ xcpkg gen-url-transform-sample

__gen_url_transform_sample() {
    SESSION_DIR="$XCPKG_HOME/run/$$"

    rm -rf     "$SESSION_DIR"
    install -d "$SESSION_DIR"
    cd         "$SESSION_DIR"

    cat > url-transform.sample <<EOF
#!/bin/sh

# https://gitmirror.com/
case \$1 in
    *githubusercontent.com/*)
        printf '%s\n' "\$1" | sed 's|githubusercontent|gitmirror|'
        ;;
    https://github.com/*)
        printf 'https://hub.gitmirror.com/%s\n' "\$1"
        ;;
    '') printf '%s\n' "\$0 <URL>, <URL> is unspecified." >&2 ; exit 1 ;;
    *)  printf '%s\n' "\$1"
esac
EOF

    chmod +x url-transform.sample

    install -d "$XCPKG_HOME"

    mv url-transform.sample "$XCPKG_HOME/"

    rm -rf "$SESSION_DIR"

    success "url-transform sample has been written into $XCPKG_HOME/url-transform.sample"
    note "You can rename url-transform.sample to url-transform then edit it to meet your needs. To apply this, you should run 'export XCPKG_URL_TRANSFORM=$XCPKG_HOME/url-transform' in your terminal."
}

# }}}
##############################################################################
# {{{ xcpkg cleanup

__cleanup() {
    success "Done."
}

# }}}
##############################################################################
# {{{ xcpkg setup

__setup() {
    __setup_uppm

    success "xcpkg have been successfully setup."
}

# use commands: uname curl tar xz cut
__setup_uppm() {
    SESSION_DIR="$XCPKG_HOME/run/$$/core"

    run rm -rf     "$SESSION_DIR"
    run install -d "$SESSION_DIR"
    run cd         "$SESSION_DIR"

    ##################################################################################

    # https://curl.se/docs/caextract.html
    wfetch 'https://curl.se/ca/cacert.pem' --no-buffer

    export SSL_CERT_FILE="$PWD/cacert.pem"

    ##################################################################################

    case "${NATIVE_PLATFORM_VERS%%.*}" in
        10) X='10.15' ;;
        11) X='11.0'  ;;
        12) X='12.0'  ;;
        13) X='13.0'  ;;
        14) X='14.0'  ;;
        *)  X='15.0'  ;;
    esac

    XCPKG_CORE_LATEST_RELEASE_VERSION="2024.10.26"
    XCPKG_CORE_LATEST_RELEASE_ARCHIVE="xcpkg-core-${XCPKG_CORE_LATEST_RELEASE_VERSION}-macos-${X}-${NATIVE_PLATFORM_ARCH}.tar.xz"

    wfetch "https://github.com/leleliu008/xcpkg/releases/download/xcpkg-core-${XCPKG_CORE_LATEST_RELEASE_VERSION}/${XCPKG_CORE_LATEST_RELEASE_ARCHIVE}" --no-buffer

    run tar xvf "$XCPKG_CORE_LATEST_RELEASE_ARCHIVE" --strip-components=1 --no-same-owner

    ##################################################################################

    run ./uppm about
    run ./uppm update

    unset UPPM_PACKAGE_EXEFIND_PATH
    unset UPPM_PACKAGE_ACLOCAL_PATH

    for item in bash coreutils findutils gawk gsed grep git curl bsdtar tree fzf bat jq yq d2 dot_static
    do
        run ./uppm install "$item"

        UPPM_PACKAGE_INSTALLED_DIR="$(./uppm info "$item" installed-dir)"

        if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/bin" ] ; then
            UPPM_PACKAGE_EXEFIND_PATH="$UPPM_PACKAGE_EXEFIND_PATH:$UPPM_PACKAGE_INSTALLED_DIR/bin"
        fi

        if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/sbin" ] ; then
            UPPM_PACKAGE_EXEFIND_PATH="$UPPM_PACKAGE_EXEFIND_PATH:$UPPM_PACKAGE_INSTALLED_DIR/sbin"
        fi

        if [ -d "$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal" ] ; then
            UPPM_PACKAGE_ACLOCAL_PATH="$UPPM_PACKAGE_ACLOCAL_PATH:$UPPM_PACKAGE_INSTALLED_DIR/share/aclocal"
        fi
    done

    UPPM_PACKAGE_EXEFIND_PATH="${UPPM_PACKAGE_EXEFIND_PATH#':'}"
    UPPM_PACKAGE_ACLOCAL_PATH="${UPPM_PACKAGE_ACLOCAL_PATH#':'}"

    ##################################################################################

    cat > init.sh <<EOF
export ACLOCAL_PATH="$UPPM_PACKAGE_ACLOCAL_PATH:\$ACLOCAL_PATH"
export PATH="$UPPM_PACKAGE_EXEFIND_PATH:\$PATH"

# https://git-scm.com/book/en/v2/Git-Internals-Environment-Variables
if [ -d "\$UPPM_HOME/installed/git/libexec/git-core" ] ; then
    export GIT_EXEC_PATH="\$UPPM_HOME/installed/git/libexec/git-core"
    export GIT_TEMPLATE_DIR="\$UPPM_HOME/installed/git/share/git-core/templates"
    export GIT_CONFIG_NOSYSTEM=1
fi
EOF

    #################################################################################

    if [ -d        "$XCPKG_CORE_DIR" ] ; then
        run rm -rf "$XCPKG_CORE_DIR"
    fi

    run mv "$SESSION_DIR" "$XCPKG_HOME/"
}

# }}}
##############################################################################
# {{{ xcpkg help

__help() {
    cat <<EOF
[38;5;199m    [38;5;163m    [38;5;164m     [38;5;128m   _[38;5;129m    [38;5;93m     
[38;5;199m__ [38;5;163m ____[38;5;164m_ _ [38;5;128m__ |[38;5;129m | __[38;5;93m__ _[38;5;99m 
[38;5;199m\ \[38;5;163m/ / [38;5;164m__| '[38;5;128m_ \|[38;5;129m |/ [38;5;93m/ _\` [38;5;99m|
[38;5;199m > [38;5;163m < ([38;5;164m__| [38;5;128m|_) |[38;5;129m   <[38;5;93m (_|[38;5;99m |
[38;5;199m/_[38;5;163m/\_\[38;5;164m___| [38;5;128m.__/[38;5;129m|_|\[38;5;93m_\__,[38;5;99m |
[38;5;199m  [38;5;163m    [38;5;164m   |[38;5;128m_|   [38;5;129m    [38;5;93m |__[38;5;99m_/  $XCPKG_VERSION
[0m
EOF

    printf '%b\n' "\
${COLOR_GREEN}A package builder/manager for Xcode to build projects written in C, C++, Rust, Zig, Go, Haskell, etc.${COLOR_OFF}

${COLOR_GREEN}xcpkg <ACTION> [ARGUMENT...]${COLOR_OFF}

${COLOR_GREEN}xcpkg help${COLOR_OFF}
${COLOR_GREEN}xcpkg --help${COLOR_OFF}
${COLOR_GREEN}xcpkg -h${COLOR_OFF}
    show help of this command.

${COLOR_GREEN}xcpkg version${COLOR_OFF}
${COLOR_GREEN}xcpkg --version${COLOR_OFF}
${COLOR_GREEN}xcpkg -V${COLOR_OFF}
    show version of this command.

${COLOR_GREEN}xcpkg setup${COLOR_OFF}
    install essential tools (e.g. uppm, bash, coreutils, findutils, gawk, gsed, grep, git, curl, bsdtar, tree, fzf, bat, jq, yq, d2, dot, etc) used by this shell script.

${COLOR_GREEN}xcpkg about${COLOR_OFF}
    show basic information about this software.

${COLOR_GREEN}xcpkg sysinfo${COLOR_OFF}
    show basic information about your current running operation system.

${COLOR_GREEN}xcpkg xcinfo [DEVELOPER-DIR]${COLOR_OFF}
    show basic information about the specified location of Xcode.

    If DEVELOPER-DIR is unspecified, the environment variable ${COLOR_RED}DEVELOPER_DIR${COLOR_OFF} is honored, if the environment variable DEVELOPER_DIR is not set, it would be determined by running command ${COLOR_PURPLE}xcode-select -p${COLOR_OFF}

${COLOR_GREEN}xcpkg completion zsh${COLOR_OFF}
    show tab-completion script for zsh.

${COLOR_GREEN}xcpkg update${COLOR_OFF}
    update all available formula repositories.

${COLOR_GREEN}xcpkg upgrade-self${COLOR_OFF}
    upgrade this software.

${COLOR_GREEN}xcpkg gen-url-transform-sample${COLOR_OFF}
    generate url-transform sample.

${COLOR_GREEN}xcpkg cleanup${COLOR_OFF}
    delete the unused cached files.


${COLOR_GREEN}xcpkg ls-available [-v] [--json | --yaml]${COLOR_OFF}
    list all available packages.

${COLOR_GREEN}xcpkg ls-installed [-v]${COLOR_OFF}
    list all installed packages.

${COLOR_GREEN}xcpkg ls-outdated [-v]${COLOR_OFF}
    list all outdated  packages.


${COLOR_GREEN}xcpkg is-available <PACKAGE-NAME>${COLOR_OFF}
    check if the given package is available.

${COLOR_GREEN}xcpkg is-installed <PACKAGE-SPEC>${COLOR_OFF}
    check if the given package is installed.

${COLOR_GREEN}xcpkg is-outdated  <PACKAGE-SPEC>${COLOR_OFF}
    check if the given package is outdated.


${COLOR_GREEN}xcpkg formula-repo-init <FORMULA-REPO-NAME> <FORMULA-REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]${COLOR_OFF}
    create a new empty formula repository.

${COLOR_GREEN}xcpkg formula-repo-add  <FORMULA-REPO-NAME> <FORMULA-REPO-URL> [--branch=VALUE --pin/--unpin --enable/--disable]${COLOR_OFF}
    create a new empty formula repository then sync with server.

${COLOR_GREEN}xcpkg formula-repo-del  <FORMULA-REPO-NAME>${COLOR_OFF}
    delete the given formula repository.

${COLOR_GREEN}xcpkg formula-repo-sync <FORMULA-REPO-NAME>${COLOR_OFF}
    update the given formula repository.

${COLOR_GREEN}xcpkg formula-repo-info <FORMULA-REPO-NAME>${COLOR_OFF}
    show information of the given formula repository.

${COLOR_GREEN}xcpkg formula-repo-conf <FORMULA-REPO-NAME> [--url=VALUE --branch=VALUE --pin/--unpin --enable/--disable]${COLOR_OFF}
    change the config of the given formula repository.

${COLOR_GREEN}xcpkg formula-repo-list${COLOR_OFF}
    list all available formula repositories.


${COLOR_GREEN}xcpkg search <REGULAR-EXPRESSION-PATTERN> [-v] [--json | --yaml]${COLOR_OFF}
    search all available packages whose name matches the given regular expression pattern.


${COLOR_GREEN}xcpkg info-available <PACKAGE-NAME> [--json | --yaml | <KEY>]${COLOR_OFF}
    show information of the given available package.

${COLOR_GREEN}xcpkg info-installed <PACKAGE-SPEC> [--json | --yaml | <KEY>]${COLOR_OFF}
    show information of the given installed package.


${COLOR_GREEN}xcpkg depends <PACKAGE-NAME> [-t <OUTPUT-TYPE>] [-e <ENGINE>] [-o <OUTPUT-PATH>]${COLOR_OFF}
    show the packages that are depended by the given package.

    <OUTPUT-TYPE> must be any one of d2 dot box svg png

    <OUTPUT-PATH> can be either the filepath or directory.

    <ENGINE> must be any one of d2 dot.

    If <OUTPUT-PATH> is . .. or ends with slash(/), then it will be treated as a directory, otherwise, it will be treated as a filepath.

    If <OUTPUT-PATH> is treated as a directory, then it will be expanded to <OUTPUT-PATH>/<PACKAGE-NAME>-dependencies.<OUTPUT-TYPE>

    If -o <OUTPUT-PATH> option is unspecified, the result will be written to stdout.

    If -t <OUTPUT-TYPE> option is unspecified, and if <OUTPUT-PATH> ends with one of .d2 .dot .box .svg .png, <OUTPUT-TYPE> will be the <OUTPUT-PATH> suffix, otherwise, <OUTPUT-TYPE> will be box.


${COLOR_GREEN}xcpkg fetch <PACKAGE-NAME>${COLOR_OFF}
    download all the resources of the given package to the local cache.


${COLOR_GREEN}xcpkg install <PACKAGE-NAME|PACKAGE-SPEC>... [INSTALL-OPTIONS]${COLOR_OFF}
    install the given packages.

    <PACKAGE-NAME> must match the regular expression pattern ${COLOR_RED}^[A-Za-z0-9+-_.@]{1,50}$ ${COLOR_OFF}

    <PACKAGE-SPEC> is a formatted string that has form ${COLOR_RED}<TARGET>/<PACKAGE-NAME>${COLOR_OFF}

    <TARGET> indicates which platform would be built for.

    <TARGET> is a formatted string that has form ${COLOR_RED}<PLATFORM-NAME>-<PLATFORM-VERSION>-<PLATFORM-ARCH>${COLOR_OFF}

    <PLATFORM-NAME> : e.g. AppleTVOS, AppleTVSimulator, DriverKit, MacOSX, WatchOS, WatchSimulator, iPhoneOS, iPhoneSimulator, etc

    <PLATFORM-VERSION> : specify the platform version to be built with. It usually matches the regular expression pattern '[0-9][0-9]?.[0-9][0-9]?', e.g. 10.15, 11.0, 12.0, 12.6, etc.

    <PLATFORM-ARCH> : e.g. x86_64, arm64, arm64e, etc

    <TARGET> examples: e.g. MacOSX-10.15-x86_64, MacOSX-13.0-arm64, iPhoneOS-12.0-arm64

    INSTALL-OPTIONS:
        ${COLOR_BLUE}--target=<TARGET>${COLOR_OFF}
            specify the target to be built for.

            If this option is unspecified, the environment variable ${COLOR_RED}XCPKG_DEFAULT_TARGET${COLOR_OFF} is honored, if the environment variable XCPKG_DEFAULT_TARGET is not set, <TARGET> will be same as your current running operation system.

        ${COLOR_BLUE}--developer-dir=<DEVELOPER_DIR>${COLOR_OFF}
            specify the Xcode developer directory.

            If --developer-dir=<DEVELOPER_DIR> is unspecified, the environment variable ${COLOR_RED}DEVELOPER_DIR${COLOR_OFF} is honored, if the environment variable DEVELOPER_DIR is not set, it would be determined by running command ${COLOR_PURPLE}xcode-select -p${COLOR_OFF}

        ${COLOR_BLUE}--profile=<debug|release>${COLOR_OFF}
            specify the build profile.

            debug:
                  CFLAGS: -O0 -g
                CXXFLAGS: -O0 -g

            release:
                  CFLAGS: -Os
                CXXFLAGS: -Os
                CPPFLAGS: -DNDEBUG
                 LDFLAGS: -flto -Wl,-S

        ${COLOR_BLUE}-j <N>${COLOR_OFF}
            specify the number of jobs you can run in parallel.

        ${COLOR_BLUE}-I <FORMULA-SEARCH-DIR>${COLOR_OFF}
            specify the formula search directory. This option can be used multiple times.

        ${COLOR_BLUE}-E${COLOR_OFF}
            export compile_commands.json

        ${COLOR_BLUE}-U${COLOR_OFF}
            upgrade packages if possible.

        ${COLOR_BLUE}-K${COLOR_OFF}
            keep the session directory even if this package is successfully installed.

        ${COLOR_BLUE}-q${COLOR_OFF}
            silent mode. no any messages will be output to terminal.

        ${COLOR_BLUE}-v${COLOR_OFF}
            verbose mode. many messages will be output to terminal.

            This option is equivalent to -v-* options all are supplied.

        ${COLOR_BLUE}-x${COLOR_OFF}
            very verbose mode. many many messages will be output to terminal.

            This option is equivalent to -v-* and -x-* options all are supplied.

        ${COLOR_BLUE}-v-env${COLOR_OFF}
            show all environment variables before starting to build.

        ${COLOR_BLUE}-v-http${COLOR_OFF}
            show http request/response.

        ${COLOR_BLUE}-v-xcode${COLOR_OFF}
            show xcode information.

        ${COLOR_BLUE}-v-formula${COLOR_OFF}
            show formula content.

        ${COLOR_BLUE}-v-go${COLOR_OFF}
            pass -v argument to go build command.

        ${COLOR_BLUE}-v-uppm${COLOR_OFF}
            pass -v argument to uppm command.

        ${COLOR_BLUE}-v-cargo${COLOR_OFF}
            pass -v argument to cargo command.

        ${COLOR_BLUE}-v-meson${COLOR_OFF}
            pass -v argument to meson command.

        ${COLOR_BLUE}-v-ninja${COLOR_OFF}
            pass -v argument to ninja command.

        ${COLOR_BLUE}-v-gmake${COLOR_OFF}
            pass V=1 argument to gmake command.

        ${COLOR_BLUE}-v-cmake${COLOR_OFF}
            set(CMAKE_VERBOSE_MAKEFILE ON)

        ${COLOR_BLUE}-v-xmake${COLOR_OFF}
            pass -v argument to xmake command.

        ${COLOR_BLUE}-x-sh${COLOR_OFF}
            set -x to debug current running shell.

        ${COLOR_BLUE}-x-cc${COLOR_OFF}
            pass -v argument to clang command.

        ${COLOR_BLUE}-x-ld${COLOR_OFF}
            pass -Wl,-v argument to linker.

        ${COLOR_BLUE}-x-go${COLOR_OFF}
            pass -x argument to go build command.

        ${COLOR_BLUE}-x-cargo${COLOR_OFF}
            pass -vv argument to cargo command.

        ${COLOR_BLUE}-x-gmake${COLOR_OFF}
            pass --debug argument to gmake command.

        ${COLOR_BLUE}-x-cmake${COLOR_OFF}
            set(CMAKE_FIND_DEBUG_MODE ON)

        ${COLOR_BLUE}-x-xmake${COLOR_OFF}
            pass -vD argument to xmake command.

        ${COLOR_BLUE}-x-pkg-config${COLOR_OFF}
            export PKG_CONFIG_DEBUG_SPEW=1

        ${COLOR_BLUE}--disable-ccache${COLOR_OFF}
            do not use ccache.

${COLOR_GREEN}xcpkg reinstall <PACKAGE-SPEC>... [INSTALL-OPTIONS]${COLOR_OFF}
    reinstall the given packages.

${COLOR_GREEN}xcpkg upgrade   <PACKAGE-SPEC>... [INSTALL-OPTIONS]${COLOR_OFF}
    upgrade the given packages. If no any packages are given, all outdated packages will to be upgraded.

${COLOR_GREEN}xcpkg uninstall <PACKAGE-SPEC>...${COLOR_OFF}
    uninstall the given packages.


${COLOR_GREEN}xcpkg tree <PACKAGE-SPEC> [--dirsfirst | -L N]${COLOR_OFF}
    list installed files of the given installed package in a tree-like format.

${COLOR_GREEN}xcpkg logs <PACKAGE-SPEC>${COLOR_OFF}
    show logs of the given installed package.

    This will launch fzf finder. press ESC key to quit.


${COLOR_GREEN}xcpkg bundle <PACKAGE-SPEC> [<OUTPUT-DIR>][<OUTPUT-FILENAME-PREFIX>]<BUNDLE-TYPE> [--exclude <PATH>] [-K]${COLOR_OFF}
    bundle the given installed package into a single archive file.

    ${COLOR_BLUE}<OUTPUT-DIR>${COLOR_OFF}
        If specified, should end with slash.

    ${COLOR_BLUE}<OUTPUT-FILENAME-PREFIX>${COLOR_OFF}
        If unspecified, use <PACKAGE-NAME>-<PACKAGE-VERSION>-<TARGET-PLATFORM-NAME>-<TARGET-PLATFORM-VERSION>-<TARGET-PLATFORM-ARCH> as default.

    ${COLOR_BLUE}<BUNDLE-TYPE>${COLOR_OFF}
        should be any one of .tar.gz .tar.xz .tar.lz .tar.bz2 .zip

    ${COLOR_BLUE}--exclude <PATH>${COLOR_OFF}
        exclude file that is not mean to be bundled into the final file.

        <PATH> is relative to the installed root directory.

        this option can be used multiple times.

    ${COLOR_BLUE}-K${COLOR_OFF}
        keep the session directory even if this package is successfully bundled.
    "
}

# }}}
##############################################################################
# {{{ xcpkg main

set -e

# If IFS is not set, the default value will be <space><tab><newline>
# https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_03
unset IFS

##################################################################################

if [ -n "$XCPKG_XTRACE" ] ; then
    set -x
fi

if [ "$(uname)" != 'Darwin' ] ; then
    abort 1 "this software can only be run on macOS."
fi

##################################################################################

XCPKG_VERSION=0.29.11

XCPKG_ARG0="$0"
XCPKG_ARG1="$1"
XCPKG_ARGV="$0 $*"

XCPKG_PATH="$(cd "$(dirname "$0")" && pwd)/${0##*/}"

XCPKG_OFFICIAL_FORMULA_REPO_URL='https://github.com/leleliu008/xcpkg-formula-repository-official-core'

XCPKG_UPGRAGE_URL='https://raw.githubusercontent.com/leleliu008/xcpkg/master/xcpkg'

XCPKG_ZSH_COMPLETION_SCRIPT_URL='https://raw.githubusercontent.com/leleliu008/xcpkg/master/_xcpkg'

[ -z "$XCPKG_HOME" ] && {
    if [ -z "$HOME" ] ; then
        abort 1 "HOME environment variable is not set."
    else
        XCPKG_HOME="$HOME/.xcpkg"
    fi
}

XCPKG_FORMULA_REPO_ROOT="$XCPKG_HOME/repos.d"

XCPKG_PACKAGE_INSTALLED_ROOT="$XCPKG_HOME/installed"
XCPKG_PACKAGE_SYMLINKED_ROOT="$XCPKG_HOME/symlinked"

XCPKG_DOWNLOADS_DIR="$XCPKG_HOME/downloads"

XCPKG_CORE_DIR="$XCPKG_HOME/core"

NATIVE_PACKAGE_INSTALLED_ROOT="$XCPKG_HOME/native"

##################################################################################

UPPM="$XCPKG_CORE_DIR/uppm"

export UPPM_HOME="$XCPKG_HOME/uppm"

if [ -n  "$XCPKG_URL_TRANSFORM" ] ; then
    export  UPPM_URL_TRANSFORM="$XCPKG_URL_TRANSFORM"
fi

##################################################################################

# https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_default_verify_paths.html
if [ -f "$XCPKG_CORE_DIR/cacert.pem" ] ; then
    export SSL_CERT_FILE="$XCPKG_CORE_DIR/cacert.pem"
fi

##################################################################################

NATIVE_PLATFORM_KIND=darwin
NATIVE_PLATFORM_TYPE=macos
NATIVE_PLATFORM_NAME=MacOSX
NATIVE_PLATFORM_VERS="$(sw_vers -productVersion)"
NATIVE_PLATFORM_ARCH="$(uname -m)"
NATIVE_PLATFORM_NCPU="$(sysctl -n machdep.cpu.thread_count)"
NATIVE_PLATFORM_EUID="$(id -u)"
NATIVE_PLATFORM_EGID="$(id -g)"

##################################################################################

TIMESTAMP_UNIX="$(date +%s)"

##################################################################################

export BAT_THEME=Dracula

##################################################################################

case $1 in
    ''|help|--help|-h)
        __help
        exit
        ;;
    version|--version|-V)
        printf '%s\n' "$XCPKG_VERSION"
        exit
        ;;
     about)
        if command -v bat > /dev/null ; then
            VIEWER='bat --language=yaml --paging=never --color=always --theme=Dracula --style=plain'
        else
            VIEWER=cat
        fi

        $VIEWER <<EOF
xcpkg.version : $XCPKG_VERSION
xcpkg.homedir : $XCPKG_HOME
xcpkg.exepath : $XCPKG_PATH
xcpkg.website : https://github.com/leleliu008/xcpkg
EOF
        if [ -f "$UPPM" ] ; then
            printf '\n'
            "$UPPM" about
        fi
        exit
        ;;
    sysinfo)
        cat <<EOF
sysinfo.ncpu: $NATIVE_PLATFORM_NCPU
sysinfo.arch: $NATIVE_PLATFORM_ARCH
sysinfo.kind: $NATIVE_PLATFORM_KIND
sysinfo.type: $NATIVE_PLATFORM_TYPE
sysinfo.vers: $NATIVE_PLATFORM_VERS
sysinfo.euid: $NATIVE_PLATFORM_EUID
sysinfo.egid: $NATIVE_PLATFORM_EGID
EOF
        exit
        ;;
    gen-url-transform-sample)
        shift
        __gen_url_transform_sample "$@"
        exit
        ;;
   setup)
        shift
        __setup "$@"
        exit
        ;;
esac

##################################################################################

[ -z  "$CARGO_HOME" ] && {
    if [ -z "$HOME" ] ; then
        abort 1 "HOME environment variable is not set."
    else
        CARGO_HOME="$HOME/.cargo"
    fi
}

bppend_to_PATH "$CARGO_HOME/bin"

##################################################################################

export PATH="$XCPKG_CORE_DIR/bin:$PATH"

##################################################################################

# https://www.gnu.org/software/automake/manual/html_node/Macro-Search-Path.html
export ACLOCAL_PATH="$XCPKG_CORE_DIR/share/aclocal"

##################################################################################

if [ -f "$XCPKG_CORE_DIR/init.sh" ] ; then
    .   "$XCPKG_CORE_DIR/init.sh"
else
    abort 1 "please run ${COLOR_GREEN}$XCPKG_ARG0 setup${COLOR_OFF} command first, then try again."
fi

##################################################################################

case $1 in
     xcinfo)
         shift
         __inspect_xcode_info "$@"
         __println_xcode_info
         ;;

    sysinfo)
        shift
        sysinfo "$@"
        ;;

    update)            shift; __sync_available_formula_repositories "$@" ;;
    formula-repo-list) shift; __list_available_formula_repositories "$@" ;;
    formula-repo-info) shift; __info_the_given_formula_repository "$@" ;;
    formula-repo-conf) shift; __conf_the_given_formula_repository "$@" ;;
    formula-repo-sync) shift; __sync_the_given_formula_repository "$@" ;;
    formula-repo-init)
        shift

        case $1 in
            official-*) abort 1 "formula repository name that starts with 'official-' is reserved for official formula repository, please use other name."
        esac

        __create_a_formula_repository "$@"
        ;;
    formula-repo-add)
        shift

        case $1 in
            official-*) abort 1 "formula repository name that starts with 'official-' is reserved for official formula repository, please use other name."
        esac

        __create_a_formula_repository_then_sync_it "$@"
        ;;
    formula-repo-del)
        shift
        __delete_a_formula_repository "$@"
        ;;

    info-available) shift; __info_the_given_available_package "$@" ;;
    info-installed) shift; __info_the_given_installed_package "$@" ;;

    ls-available) shift; __list_available_packages "$@" ;;
    ls-installed) shift; __list_installed_packages "$@" ;;
    ls-outdated)  shift; __list__outdated_packages "$@" ;;

    is-available) shift; is_package_available "$@" ;;

    is-installed)
        shift
        PACKAGE_SPEC=
        PACKAGE_SPEC="$(inspect_package_spec "$1")"
        is_package_installed "$PACKAGE_SPEC"
        ;;

    is-outdated)
        shift
        PACKAGE_SPEC=
        PACKAGE_SPEC="$(inspect_package_spec "$1")"
        is_package__outdated "$PACKAGE_SPEC"
        ;;

    search)  shift; __search_packages "$@" ;;

    depends) shift; __show_packages_depended_by_the_given_package "$@" ;;
    fetch)   shift;        __fetch_resources_of_the_given_package "$@" ;;

    install) shift;   __install_the_given_packages "$@" ;;
  reinstall) shift; __reinstall_the_given_packages "$@" ;;
  uninstall) shift; __uninstall_the_given_packages "$@" ;;

    upgrade) shift; __upgrade_packages "$@" ;;

    upgrade-self)
             shift; __upgrade_self "$XCPKG_UPGRAGE_URL" "$@" ;;

    logs)   shift;   __logs_the_given_installed_package "$@" ;;
    tree)   shift;   __tree_the_given_installed_package "$@" ;;
    bundle) shift; __bundle_the_given_installed_package "$@" ;;

    completion)
        shift
        case $1 in
            zsh)
                shift
                __zsh_completions "$XCPKG_ZSH_COMPLETION_SCRIPT_URL" "$@"
                ;;
            *)  abort 1 "xcpkg completion $1: not support."
        esac
        ;;

    cleanup) shift; __cleanup ;;

    run)
        shift

        [ -z "$1" ] && abort 1 'no command is supplied to run.'

        [ "$1" = uppm ] && {
            shift
            "$UPPM" "$@"
            exit
        }

        unset DIRS1
        unset DIRS1
        unset DIRS3

        ROOT1="$UPPM_HOME/installed"

        if [ -d "$ROOT1" ] ; then
            DIRS1="$(find "$ROOT1" -maxdepth 1 -mindepth 1 -type d)"
        fi

        ROOT2="$NATIVE_PACKAGE_INSTALLED_ROOT"

        if [ -d "$ROOT2" ] ; then
            DIRS2="$(find "$ROOT2" -maxdepth 1 -mindepth 1 -type l)"
        fi

        ROOT3="$XCPKG_PACKAGE_INSTALLED_ROOT/$NATIVE_PLATFORM_NAME-$NATIVE_PLATFORM_VERS-$NATIVE_PLATFORM_ARCH"

        if [ -d "$ROOT3" ] ; then
            DIRS3="$(find "$ROOT3" -maxdepth 1 -mindepth 1 -type l)"
        fi

        for DIR in $DIRS1 $DIRS2 $DIRS3
        do
            if [ -d  "$DIR/bin" ] ; then
                PATH="$DIR/bin:$PATH"
            fi

            if [ -d  "$DIR/sbin" ] ; then
                PATH="$DIR/sbin:$PATH"
            fi

            if [ -d  "$DIR/include" ] ; then
                CPPFLAGS="-I$DIR/include $CPPFLAGS"
            fi

            if [ -d  "$DIR/lib" ] ; then
                LDFLAGS="-L$DIR/lib -Wl,-rpath,$DIR/lib $LDFLAGS"
            fi

            if [ -d  "$DIR/lib/pkgconfig" ] ; then
                PKG_CONFIG_PATH="$DIR/lib/pkgconfig:$PKG_CONFIG_PATH"
            fi

            SHARED="$DIR/share"

            if [ -d "$SHARED" ] ; then
                if [ -d "$SHARED/pkgconfig" ] ; then
                    PKG_CONFIG_PATH="$SHARED/pkgconfig:$PKG_CONFIG_PATH"
                fi

                if [ -d  "$SHARED/aclocal" ] ; then
                    ACLOCAL_PATH="$SHARED/aclocal:$ACLOCAL_PATH"
                fi

                # https://gi.readthedocs.io/en/latest/tools/g-ir-scanner.html#environment-variables
                # https://help.gnome.org/admin//system-admin-guide/2.32/mimetypes-database.html.en

                for item in gir-1.0 mime
                do
                    if [ -d "$SHARED/$item" ] ; then
                        if [ -z "$XDG_DATA_DIRS" ] ; then
                            XDG_DATA_DIRS="$SHARED"
                        else
                            XDG_DATA_DIRS="$SHARED:$XDG_DATA_DIRS"
                        fi

                        break
                    fi
                done
            fi
        done

        export CPPFLAGS
        export CFLAGS
        export LDFLAG
        export PKG_CONFIG_PATH
        export ACLOCAL_PATH
        export XDG_DATA_DIRS

        #export -p

        "$@"
        ;;

    *)  abort 1 "unrecognized argument: $1"
esac

# }}}
